From 213915b74b47767874648fd58acb0377fc102fd0 Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Sat, 20 Aug 2022 18:38:42 +0800 Subject: [PATCH 01/10] migrate some `rustc_borrowck` diagnostic --- compiler/rustc_borrowck/src/lib.rs | 19 ++++++-------- .../src/region_infer/opaque_types.rs | 18 ++++++------- .../rustc_borrowck/src/session_diagnostics.rs | 25 ++++++++++++++++++- .../locales/en-US/borrowck.ftl | 13 +++++++++- 4 files changed, 50 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 4ad9a970bc1be..2828b972c5f99 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -18,7 +18,7 @@ extern crate tracing; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::dominators::Dominators; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::ChunkedBitSet; @@ -424,17 +424,12 @@ fn do_mir_borrowck<'a, 'tcx>( continue; } - tcx.struct_span_lint_hir(UNUSED_MUT, lint_root, span, |lint| { - let mut_span = tcx.sess.source_map().span_until_non_whitespace(span); - lint.build("variable does not need to be mutable") - .span_suggestion_short( - mut_span, - "remove this `mut`", - "", - Applicability::MachineApplicable, - ) - .emit(); - }) + tcx.emit_spanned_lint( + UNUSED_MUT, + lint_root, + span, + session_diagnostics::VarBetterNotMut { span }, + ) } let tainted_by_errors = mbcx.emit_errors(); diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index d6712b6a4799c..b0d7253651b09 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -16,6 +16,8 @@ use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; use rustc_trait_selection::traits::TraitEngineExt as _; +use crate::session_diagnostics::ConstNotUsedTraitAlias; + use super::RegionInferenceContext; impl<'tcx> RegionInferenceContext<'tcx> { @@ -639,17 +641,11 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { Some(GenericArgKind::Const(c1)) => c1, Some(u) => panic!("const mapped to unexpected kind: {:?}", u), None => { - self.tcx - .sess - .struct_span_err( - self.span, - &format!( - "const parameter `{}` is part of concrete type but not \ - used in parameter list for the `impl Trait` type alias", - ct - ), - ) - .emit(); + //FIXME! + self.tcx.sess.emit_err(ConstNotUsedTraitAlias { + ct: ct.to_string(), + span: self.span, + }); self.tcx().const_error(ct.ty()) } diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 895723d44ff1b..c879988b76af4 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -1,7 +1,15 @@ -use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; +use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_middle::ty::Ty; use rustc_span::Span; +#[derive(SessionDiagnostic)] +#[error(borrowck::move_borrowed, code = "E0505")] +pub(crate) struct MoveBorrowed<'cx> { + #[primary_span] + pub span: Span, + pub desc: &'cx str, +} + #[derive(SessionDiagnostic)] #[error(borrowck::move_unsized, code = "E0161")] pub(crate) struct MoveUnsized<'tcx> { @@ -42,3 +50,18 @@ pub(crate) struct GenericDoesNotLiveLongEnough { #[primary_span] pub span: Span, } + +#[derive(LintDiagnostic)] +#[lint(borrowck::var_better_not_mut)] +pub(crate) struct VarBetterNotMut { + #[suggestion_short(applicability = "machine-applicable", code = "")] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(borrowck::const_not_used_in_type_alias)] +pub(crate) struct ConstNotUsedTraitAlias { + pub ct: String, + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index 4af40d2062d3a..51f174df44d06 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -15,4 +15,15 @@ borrowck_higher_ranked_subtype_error = higher-ranked subtype error generic_does_not_live_long_enough = - `{$kind}` does not live long enough \ No newline at end of file + `{$kind}` does not live long enough + +borrowck_move_borrowed = + cannot move out of `{$desc}` beacause it is borrowed + +borrowck_var_better_not_mut = + variable does not need to be mutable + .suggestion = remove this `mut` + +borrowck_const_not_used_in_type_alias = + const parameter `{$ct}` is part of concrete type but not \ + used in parameter list for the `impl Trait` type alias From 2ad89c9768e94f0c4701b5268044391b3cb93730 Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Sun, 21 Aug 2022 12:11:21 +0800 Subject: [PATCH 02/10] fluent / remove --- compiler/rustc_error_messages/locales/en-US/borrowck.ftl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index 51f174df44d06..a5ce441f4a787 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -25,5 +25,4 @@ borrowck_var_better_not_mut = .suggestion = remove this `mut` borrowck_const_not_used_in_type_alias = - const parameter `{$ct}` is part of concrete type but not \ - used in parameter list for the `impl Trait` type alias + const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias From 5629970e724723f0ed3310e7269adeb202dcf66c Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Sun, 21 Aug 2022 22:24:42 +0800 Subject: [PATCH 03/10] region_err --- .../src/diagnostics/region_errors.rs | 95 +++++++++---------- .../rustc_borrowck/src/session_diagnostics.rs | 75 +++++++++++++++ .../locales/en-US/borrowck.ftl | 29 ++++++ 3 files changed, 148 insertions(+), 51 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 0dce5be953e1a..d28187dc42de4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! Error reporting machinery for lifetime errors. use rustc_data_structures::fx::FxHashSet; @@ -23,7 +25,10 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; use crate::borrowck_errors; -use crate::session_diagnostics::GenericDoesNotLiveLongEnough; +use crate::session_diagnostics::{ + FnMutError, FnMutReturnTypeErr, GenericDoesNotLiveLongEnough, LifeTimeOutLiveErr, + LifeTimeReturnCategoryErr, +}; use super::{OutlivesSuggestionBuilder, RegionName}; use crate::region_infer::BlameConstraint; @@ -488,12 +493,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let ErrorConstraintInfo { outlived_fr, span, .. } = errci; - let mut diag = self - .infcx - .tcx - .sess - .struct_span_err(*span, "captured variable cannot escape `FnMut` closure body"); - let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty; if let ty::Opaque(def_id, _) = *output_ty.kind() { output_ty = self.infcx.tcx.type_of(def_id) @@ -501,19 +500,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { debug!("report_fnmut_error: output_ty={:?}", output_ty); - let message = match output_ty.kind() { - ty::Closure(_, _) => { - "returns a closure that contains a reference to a captured variable, which then \ - escapes the closure body" - } + let ty_err = match output_ty.kind() { + ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span }, ty::Adt(def, _) if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) => { - "returns an `async` block that contains a reference to a captured variable, which then \ - escapes the closure body" + FnMutReturnTypeErr::ReturnAsyncBlock { span: *span } } - _ => "returns a reference to a captured variable which escapes the closure body", + _ => FnMutReturnTypeErr::ReturnRef { span: *span }, }; - diag.span_label(*span, message); + let mut err = FnMutError { + span: *span, + ty_err, + upvar_def_span: None, + upvar_span: None, + fr_span: None, + }; if let ReturnConstraint::ClosureUpvar(upvar_field) = kind { let def_id = match self.regioncx.universal_regions().defining_ty { @@ -532,20 +533,17 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let upvars_map = self.infcx.tcx.upvars_mentioned(def_id).unwrap(); let upvar_def_span = self.infcx.tcx.hir().span(def_hir); let upvar_span = upvars_map.get(&def_hir).unwrap().span; - diag.span_label(upvar_def_span, "variable defined here"); - diag.span_label(upvar_span, "variable captured here"); + err.upvar_def_span = Some(upvar_def_span); + err.upvar_span = Some(upvar_span); } } if let Some(fr_span) = self.give_region_a_name(*outlived_fr).unwrap().span() { - diag.span_label(fr_span, "inferred to be a `FnMut` closure"); + err.fr_span = Some(fr_span); } - diag.note( - "`FnMut` closures only have access to their captured variables while they are \ - executing...", - ); - diag.note("...therefore, they cannot allow references to captured variables to escape"); + let mut diag = self.infcx.tcx.sess.create_err(err); + self.suggest_move_on_borrowing_closure(&mut diag); diag @@ -681,39 +679,33 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { .. } = errci; - let mut diag = - self.infcx.tcx.sess.struct_span_err(*span, "lifetime may not live long enough"); - let (_, mir_def_name) = self.infcx.tcx.article_and_description(self.mir_def_id().to_def_id()); let fr_name = self.give_region_a_name(*fr).unwrap(); - fr_name.highlight_region_name(&mut diag); let outlived_fr_name = self.give_region_a_name(*outlived_fr).unwrap(); - outlived_fr_name.highlight_region_name(&mut diag); - match (category, outlived_fr_is_local, fr_is_local) { - (ConstraintCategory::Return(_), true, _) => { - diag.span_label( - *span, - format!( - "{mir_def_name} was supposed to return data with lifetime `{outlived_fr_name}` but it is returning \ - data with lifetime `{fr_name}`", - ), - ); - } - _ => { - diag.span_label( - *span, - format!( - "{}requires that `{}` must outlive `{}`", - category.description(), - fr_name, - outlived_fr_name, - ), - ); - } - } + let err_category = match (category, outlived_fr_is_local, fr_is_local) { + (ConstraintCategory::Return(_), true, _) => LifeTimeReturnCategoryErr::WrongReturn { + span: *span, + mir_def_name: mir_def_name.to_string(), + outlived_fr_name: outlived_fr_name.to_string(), + fr_name: fr_name.to_string(), + }, + _ => LifeTimeReturnCategoryErr::ShortReturn { + span: *span, + category_desc: category.description().to_string(), + free_region_name: fr_name.to_string(), + outlived_fr_name: outlived_fr_name.to_string(), + }, + }; + + let err = LifeTimeOutLiveErr { span: *span, category: err_category }; + + let mut diag = self.infcx.tcx.sess.create_err(err); + + fr_name.highlight_region_name(&mut diag); + outlived_fr_name.highlight_region_name(&mut diag); self.add_static_impl_trait_suggestion(&mut diag, *fr, fr_name, *outlived_fr); self.suggest_adding_lifetime_params(&mut diag, *fr, *outlived_fr); @@ -862,6 +854,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ident.span, "calling this method introduces the `impl`'s 'static` requirement", ); + // TODO! err.span_note(multi_span, "the used `impl` has a `'static` requirement"); err.span_suggestion_verbose( span.shrink_to_hi(), diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index c879988b76af4..3a24b28da3556 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -1,3 +1,4 @@ +use rustc_errors::MultiSpan; use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_middle::ty::Ty; use rustc_span::Span; @@ -65,3 +66,77 @@ pub(crate) struct ConstNotUsedTraitAlias { #[primary_span] pub span: Span, } + +#[derive(SessionDiagnostic)] +#[error(borrowck::var_cannot_escape_closure)] +#[note] +#[note(borrowck::cannot_escape)] +pub(crate) struct FnMutError { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub ty_err: FnMutReturnTypeErr, + #[label(borrowck::upvar_def)] + pub upvar_def_span: Option, + #[label(borrowck::upvar)] + pub upvar_span: Option, + #[label(borrowck::fr)] + pub fr_span: Option, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum FnMutReturnTypeErr { + #[label(borrowck::returned_closure_escaped)] + ReturnClosure { + #[primary_span] + span: Span, + }, + #[label(borrowck::returned_async_block_escaped)] + ReturnAsyncBlock { + #[primary_span] + span: Span, + }, + #[label(borrowck::returned_ref_escaped)] + ReturnRef { + #[primary_span] + span: Span, + }, +} + +#[derive(SessionDiagnostic)] +#[error(borrowck::lifetime_constraints_error)] +pub(crate) struct LifeTimeOutLiveErr { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub category: LifeTimeReturnCategoryErr, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum LifeTimeReturnCategoryErr { + #[label(borrowck::returned_lifetime_wrong)] + WrongReturn { + #[primary_span] + span: Span, + mir_def_name: String, + outlived_fr_name: String, + fr_name: String, + }, + #[label(borrowck::returned_lifetime_short)] + ShortReturn { + #[primary_span] + span: Span, + category_desc: String, + free_region_name: String, + outlived_fr_name: String, + }, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum StaticLifeTimeRequireErr { + #[note(borrowck::impl_require_static)] + UsedImpl { + #[primary_span] + span: MultiSpan, + }, +} diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index a5ce441f4a787..02db2fae7c46e 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -26,3 +26,32 @@ borrowck_var_better_not_mut = borrowck_const_not_used_in_type_alias = const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias + +borrowck_var_cannot_escape_closure = + captured variable cannot escape `FnMut` closure body + .upvar_def = variable defined here + .upvar = variable captured here + .fr = "inferred to be a `FnMut` closure" + .note = `FnMut` closures only have access to their captured variables while they are executing... + .cannot_escape = ...therefore, they cannot allow references to captured variables to escape + +borrowck_returned_closure_escaped = + returns a closure that contains a reference to a captured variable, which then escapes the closure body + +borrowck_returned_async_block_escaped = + returns an `async` block that contains a reference to a captured variable, which then escapes the closure body + +borrowck_returned_ref_escaped = + returns a reference to a captured variable which escapes the closure body + +borrowck_lifetime_constraints_error = + lifetime may not live long enough + +borrowck_returned_lifetime_wrong = + {$mir_def_name} was supposed to return data with lifetime `{$outlived_fr_name}` but it is returning data with lifetime `{$fr_name}` + +borrowck_returned_lifetime_short = + {$category_desc}requires that `{$free_region_name}` must outlive `{$outlived_fr_name}`" + +borrowck_impl_require_static = + the used `impl` has a `'static` requirement \ No newline at end of file From d35c9ac668ef712272cfc0d6b5aa10e17c205272 Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Mon, 22 Aug 2022 15:56:40 +0800 Subject: [PATCH 04/10] more diag migrate --- .gitignore | 1 + Cargo.lock | 4 +- compiler/rustc_arena/src/lib.rs | 2 +- compiler/rustc_ast/src/ast.rs | 12 +- compiler/rustc_ast/src/ast_traits.rs | 47 +- compiler/rustc_ast/src/attr/mod.rs | 3 +- compiler/rustc_ast/src/mut_visit.rs | 34 +- compiler/rustc_ast_lowering/src/expr.rs | 50 +- .../src/diagnostics/region_errors.rs | 1 - compiler/rustc_borrowck/src/lib.rs | 9 +- .../src/region_infer/opaque_types.rs | 1 - .../rustc_borrowck/src/session_diagnostics.rs | 36 +- .../src/type_check/canonical.rs | 7 +- .../src/type_check/free_region_relations.rs | 2 +- compiler/rustc_borrowck/src/type_check/mod.rs | 139 ++-- compiler/rustc_builtin_macros/src/asm.rs | 2 +- .../src/assert/context.rs | 3 +- compiler/rustc_builtin_macros/src/cfg.rs | 4 +- .../src/deriving/clone.rs | 2 +- .../src/deriving/cmp/eq.rs | 2 +- .../src/deriving/cmp/ord.rs | 2 +- .../src/deriving/cmp/partial_eq.rs | 2 +- .../src/deriving/cmp/partial_ord.rs | 2 +- .../src/deriving/debug.rs | 2 +- .../src/deriving/decodable.rs | 2 +- .../src/deriving/default.rs | 6 +- .../src/deriving/encodable.rs | 4 +- .../src/deriving/generic/mod.rs | 6 +- .../rustc_builtin_macros/src/deriving/hash.rs | 4 +- .../rustc_builtin_macros/src/deriving/mod.rs | 2 +- .../src/global_allocator.rs | 6 +- .../src/proc_macro_harness.rs | 2 +- .../src/standard_library_imports.rs | 4 +- compiler/rustc_builtin_macros/src/test.rs | 5 +- .../rustc_builtin_macros/src/test_harness.rs | 8 +- .../example/alloc_system.rs | 2 +- .../rustc_codegen_gcc/example/alloc_system.rs | 2 +- compiler/rustc_const_eval/src/errors.rs | 18 +- .../rustc_data_structures/src/map_in_place.rs | 127 ++-- .../rustc_data_structures/src/thin_vec.rs | 45 ++ compiler/rustc_driver/src/lib.rs | 2 +- .../locales/en-US/borrowck.ftl | 30 +- .../locales/en-US/expand.ftl | 6 +- .../rustc_errors/src/diagnostic_builder.rs | 30 + compiler/rustc_errors/src/lib.rs | 9 + compiler/rustc_expand/src/base.rs | 4 +- compiler/rustc_expand/src/build.rs | 6 +- compiler/rustc_expand/src/config.rs | 8 +- compiler/rustc_expand/src/errors.rs | 12 +- compiler/rustc_expand/src/expand.rs | 16 +- compiler/rustc_expand/src/module.rs | 8 +- compiler/rustc_expand/src/placeholders.rs | 2 +- .../src/infer/error_reporting/mod.rs | 10 +- .../mismatched_static_lifetime.rs | 3 +- .../nice_region_error/placeholder_error.rs | 5 +- .../nice_region_error/static_impl_trait.rs | 2 +- .../src/infer/error_reporting/note.rs | 4 +- .../src/infer/outlives/obligations.rs | 3 +- compiler/rustc_interface/src/passes.rs | 4 +- compiler/rustc_lint/src/types.rs | 2 +- .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 25 +- .../src/diagnostics/diagnostic.rs | 82 +-- .../src/diagnostics/diagnostic_builder.rs | 87 ++- compiler/rustc_macros/src/diagnostics/mod.rs | 4 +- compiler/rustc_macros/src/lib.rs | 8 +- compiler/rustc_middle/src/traits/mod.rs | 16 +- compiler/rustc_middle/src/ty/generics.rs | 15 + compiler/rustc_monomorphize/src/collector.rs | 12 +- compiler/rustc_parse/src/lib.rs | 4 +- compiler/rustc_parse/src/parser/attr.rs | 8 +- .../rustc_parse/src/parser/attr_wrapper.rs | 17 +- .../rustc_parse/src/parser/diagnostics.rs | 18 +- compiler/rustc_parse/src/parser/expr.rs | 24 +- compiler/rustc_parse/src/parser/generics.rs | 14 +- compiler/rustc_parse/src/parser/item.rs | 57 +- compiler/rustc_parse/src/parser/pat.rs | 8 +- compiler/rustc_parse/src/parser/stmt.rs | 16 +- compiler/rustc_passes/src/errors.rs | 171 +++-- compiler/rustc_privacy/src/errors.rs | 14 +- compiler/rustc_serialize/src/serialize.rs | 2 +- compiler/rustc_session/src/parse.rs | 10 +- compiler/rustc_span/src/lib.rs | 10 + .../src/traits/error_reporting/mod.rs | 28 +- .../error_reporting/on_unimplemented.rs | 4 +- .../src/traits/error_reporting/suggestions.rs | 231 ++++--- .../rustc_trait_selection/src/traits/mod.rs | 14 +- .../rustc_trait_selection/src/traits/util.rs | 25 +- .../rustc_trait_selection/src/traits/wf.rs | 2 +- compiler/rustc_transmute/src/lib.rs | 2 + .../rustc_typeck/src/check/compare_method.rs | 2 +- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 70 +- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 602 ++++++++++++------ .../rustc_typeck/src/check/method/confirm.rs | 14 +- compiler/rustc_typeck/src/check/method/mod.rs | 7 +- .../rustc_typeck/src/check/method/probe.rs | 7 +- compiler/rustc_typeck/src/errors.rs | 54 +- library/alloc/src/alloc/tests.rs | 2 +- .../alloc/src/collections/vec_deque/mod.rs | 4 +- library/alloc/src/ffi/c_str.rs | 6 +- library/alloc/src/slice.rs | 6 +- library/alloc/src/vec/in_place_collect.rs | 2 +- library/alloc/src/vec/into_iter.rs | 6 +- library/alloc/src/vec/mod.rs | 14 +- library/alloc/src/vec/spec_extend.rs | 2 +- library/alloc/tests/str.rs | 10 +- library/core/src/intrinsics.rs | 4 +- library/core/src/num/f32.rs | 13 +- library/core/src/num/f64.rs | 13 +- library/core/src/slice/mod.rs | 15 +- library/core/src/slice/sort.rs | 36 +- library/core/src/str/validations.rs | 4 +- library/core/src/sync/atomic.rs | 14 +- library/panic_abort/src/android.rs | 2 +- library/panic_unwind/src/dwarf/eh.rs | 2 +- library/std/src/os/unix/net/addr.rs | 2 +- library/std/src/process.rs | 10 +- .../std/src/sys/sgx/abi/usercalls/tests.rs | 4 +- library/std/src/sys/windows/alloc.rs | 4 +- library/std/src/sys/windows/fs.rs | 6 +- library/std/src/sys/windows/os.rs | 6 +- src/bootstrap/bin/rustc.rs | 15 +- src/bootstrap/builder.rs | 2 +- src/librustdoc/Cargo.toml | 2 +- src/librustdoc/clean/auto_trait.rs | 12 +- src/librustdoc/clean/inline.rs | 4 +- src/librustdoc/clean/mod.rs | 35 +- src/librustdoc/clean/types.rs | 35 +- src/librustdoc/formats/cache.rs | 2 +- src/librustdoc/html/format.rs | 7 +- src/librustdoc/html/highlight.rs | 224 ++++--- .../html/highlight/fixtures/decorations.html | 6 +- .../html/highlight/fixtures/sample.html | 15 +- .../html/highlight/fixtures/sample.rs | 1 + src/librustdoc/html/highlight/tests.rs | 7 +- src/librustdoc/html/render/mod.rs | 4 +- src/librustdoc/json/conversions.rs | 6 +- .../assembly/x86_64-floating-point-clamp.rs | 25 + src/test/codegen/pic-relocation-model.rs | 2 +- src/test/codegen/pie-relocation-model.rs | 2 +- src/test/rustdoc/issue-41783.codeblock.html | 4 +- src/test/rustdoc/issue-41783.rs | 6 +- .../ui-fulldeps/internal-lints/diagnostics.rs | 2 +- src/test/ui-fulldeps/pprust-expr-roundtrip.rs | 5 +- .../session-diagnostic/diagnostic-derive.rs | 211 +++--- .../diagnostic-derive.stderr | 338 +++++----- .../associated-types-eq-3.stderr | 4 +- .../associated-types-path-2.stderr | 10 +- .../issue-27675-unchecked-bounds.stderr | 6 +- .../issue-67252-unnamed-future.stderr | 10 +- src/test/ui/async-await/issue-68112.stderr | 14 +- .../issue-65436-raw-ptr-not-send.stderr | 10 +- ...ault-trait-impl-constituent-types-2.stderr | 4 +- ...ypeck-default-trait-impl-precedence.stderr | 4 +- src/test/ui/chalkify/type_wf.rs | 4 +- src/test/ui/chalkify/type_wf.stderr | 6 +- .../closure_context/issue-26046-fn-mut.stderr | 2 + .../issue-26046-fn-once.stderr | 2 + .../closure-origin-array-diagnostics.stderr | 10 +- .../closure-origin-tuple-diagnostics.stderr | 10 +- src/test/ui/closures/closure-move-sync.stderr | 18 +- .../ui/closures/closure-wrong-kind.stderr | 10 +- .../defaults/trait_objects_fail.stderr | 8 +- .../abstract-const-as-cast-3.stderr | 16 +- .../ui/consts/const-block-const-bound.stderr | 4 +- src/test/ui/derives/deriving-copyclone.stderr | 6 +- ...e-21659-show-relevant-trait-impls-1.stderr | 6 +- ...e-21659-show-relevant-trait-impls-2.stderr | 6 +- src/test/ui/error-codes/E0277-2.stderr | 4 +- .../ui/extern/extern-types-unsized.stderr | 12 +- .../feature-gate-unsized_fn_params.stderr | 4 +- src/test/ui/fmt/send-sync.stderr | 12 +- .../drop-tracking-parent-expression.stderr | 12 +- src/test/ui/generator/drop-yield-twice.stderr | 12 +- ...erator-yielding-or-returning-itself.stderr | 26 +- src/test/ui/generator/issue-68112.rs | 1 + src/test/ui/generator/issue-68112.stderr | 10 +- src/test/ui/generator/not-send-sync.stderr | 26 +- src/test/ui/generator/partial-drop.stderr | 39 +- .../print/generator-print-verbose-1.stderr | 10 +- .../print/generator-print-verbose-2.stderr | 26 +- .../bugs/issue-88460.stderr | 6 +- .../issue-62529-3.stderr | 6 +- src/test/ui/inference/issue-71732.stderr | 6 +- src/test/ui/inference/issue-86162-1.stderr | 2 +- src/test/ui/inference/issue-86162-2.stderr | 2 +- .../interior-mutability.stderr | 6 +- src/test/ui/issues/issue-20162.stderr | 6 +- src/test/ui/issues/issue-20605.stderr | 2 +- src/test/ui/issues/issue-21763.stderr | 4 +- src/test/ui/issues/issue-31173.rs | 2 +- src/test/ui/issues/issue-31173.stderr | 30 +- src/test/ui/issues/issue-33941.stderr | 6 +- src/test/ui/issues/issue-34334.stderr | 6 +- src/test/ui/issues/issue-34349.stderr | 10 +- src/test/ui/issues/issue-59488.rs | 1 + src/test/ui/issues/issue-59488.stderr | 21 +- src/test/ui/issues/issue-60218.stderr | 4 +- ...e-66923-show-error-for-correct-call.stderr | 12 +- src/test/ui/issues/issue-69455.stderr | 2 +- src/test/ui/iterators/collect-into-array.rs | 1 + .../ui/iterators/collect-into-array.stderr | 6 +- src/test/ui/iterators/collect-into-slice.rs | 5 + .../ui/iterators/collect-into-slice.stderr | 23 +- .../ui/kindck/kindck-impl-type-params-2.rs | 2 +- .../kindck/kindck-impl-type-params-2.stderr | 2 +- .../kindck-inherited-copy-bound.curr.stderr | 2 +- ...copy-bound.object_safe_for_dispatch.stderr | 2 +- .../ui/kindck/kindck-nonsendable-1.stderr | 10 +- src/test/ui/kindck/kindck-send-object.stderr | 8 +- src/test/ui/kindck/kindck-send-object1.stderr | 8 +- src/test/ui/kindck/kindck-send-object2.stderr | 8 +- src/test/ui/kindck/kindck-send-owned.stderr | 4 +- .../branches.stderr | 6 +- .../recursion4.stderr | 12 +- .../method-help-unsatisfied-bound.stderr | 6 +- .../defaulted-never-note.fallback.stderr | 6 +- .../ui/never_type/defaulted-never-note.rs | 1 + ...diverging-fallback-no-leak.fallback.stderr | 6 +- .../feature-gate-never_type_fallback.stderr | 8 +- ...lue-fallback-issue-66757.nofallback.stderr | 6 +- src/test/ui/no-send-res-ports.stderr | 17 +- src/test/ui/not-clone-closure.stderr | 6 +- src/test/ui/not-panic/not-panic-safe-2.stderr | 8 +- src/test/ui/not-panic/not-panic-safe-3.stderr | 8 +- src/test/ui/not-panic/not-panic-safe-4.stderr | 8 +- src/test/ui/not-panic/not-panic-safe-5.stderr | 4 +- src/test/ui/not-panic/not-panic-safe-6.stderr | 8 +- .../ui/on-unimplemented/multiple-impls.stderr | 12 +- src/test/ui/on-unimplemented/on-impl.stderr | 4 +- ...invalid-syntax-in-enum-discriminant.stderr | 4 +- .../move-ref-patterns-closure-captures.stderr | 30 +- src/test/ui/proc-macro/signature.stderr | 5 +- src/test/ui/range/range-1.stderr | 2 +- .../const-default-method-bodies.stderr | 10 +- .../const-drop-fail.precise.stderr | 4 +- .../const-drop-fail.stock.stderr | 4 +- .../cross-crate.gatednc.stderr | 10 +- .../cross-crate.stocknc.stderr | 10 +- ...-method-body-is-const-same-trait-ck.stderr | 10 +- .../trait-where-clause.stderr | 12 +- src/test/ui/stats/hir-stats.stderr | 134 ++-- .../expected-boxed-future-isnt-pinned.stderr | 12 +- ...-trait-object-literal-bound-regions.stderr | 6 +- .../imm-ref-trait-object-literal.stderr | 2 +- src/test/ui/suggestions/issue-62843.stderr | 2 +- .../issue-71394-no-from-impl.stderr | 6 +- src/test/ui/suggestions/issue-84973-2.stderr | 2 +- .../suggestions/issue-84973-blacklist.stderr | 6 +- .../suggestions/issue-84973-negative.stderr | 2 +- src/test/ui/suggestions/issue-84973.stderr | 2 +- .../ui/suggestions/slice-issue-87994.stderr | 8 +- ...dding-reference-to-trait-assoc-item.stderr | 4 +- .../suggest-borrow-to-dyn-object.stderr | 4 +- ...ggest-imm-mut-trait-implementations.stderr | 6 +- .../check-trait-object-bounds-1.stderr | 4 +- .../check-trait-object-bounds-2.stderr | 4 +- .../check-trait-object-bounds-4.stderr | 4 +- .../ui/traits/bad-method-typaram-kind.stderr | 4 +- .../bound/assoc-fn-bound-root-obligation.rs | 1 - .../assoc-fn-bound-root-obligation.stderr | 6 +- .../bound/on-structs-and-enums-locals.rs | 2 +- .../bound/on-structs-and-enums-locals.stderr | 6 +- .../traits/bound/on-structs-and-enums-xc1.rs | 2 +- .../bound/on-structs-and-enums-xc1.stderr | 6 +- .../repeated-supertrait-ambig.stderr | 30 +- src/test/ui/traits/issue-77982.stderr | 8 +- src/test/ui/traits/issue-97576.stderr | 6 +- .../multidispatch-convert-ambig-dest.stderr | 10 +- .../negated-auto-traits-error.stderr | 2 +- .../ui/traits/suggest-where-clause.stderr | 4 +- src/test/ui/transmutability/references.stderr | 4 +- .../type-params-in-different-spaces-2.stderr | 12 +- ...ck-default-trait-impl-negation-sync.stderr | 8 +- .../ui/ufcs/ufcs-qpath-self-mismatch.stderr | 6 +- ...-infer-fn-once-move-from-projection.stderr | 12 +- .../ui/union/union-generic.mirunsafeck.stderr | 4 +- .../union/union-generic.thirunsafeck.stderr | 4 +- .../ui/unsized-locals/unsized-exprs.stderr | 4 +- src/test/ui/unsized/issue-30355.stderr | 4 +- src/test/ui/unsized/issue-71659.stderr | 6 +- src/test/ui/unsized/issue-75707.stderr | 4 +- src/test/ui/unsized/unsized-fn-param.stderr | 16 +- src/test/ui/unsized/unsized-struct.stderr | 4 +- src/test/ui/unsized/unsized3.stderr | 10 +- .../where-clause-method-substituion.stderr | 4 +- .../where-clauses-method-unsatisfied.stderr | 6 +- src/tools/rustfmt/src/attr.rs | 5 +- src/tools/rustfmt/src/imports.rs | 4 +- src/tools/rustfmt/src/modules.rs | 8 +- src/tools/rustfmt/src/parse/parser.rs | 2 +- src/tools/tidy/src/style.rs | 15 +- 291 files changed, 2761 insertions(+), 2103 deletions(-) create mode 100644 src/test/assembly/x86_64-floating-point-clamp.rs diff --git a/.gitignore b/.gitignore index a6625ac2ac4a1..b16fb6341c2e5 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ no_llvm_build /llvm/ /mingw-build/ /build/ +/build-rust-analyzer/ /dist/ /unicode-downloads /target diff --git a/Cargo.lock b/Cargo.lock index 293fc30903df0..3a35985836c93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2415,9 +2415,9 @@ dependencies = [ [[package]] name = "minifier" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac96d1e7a65f206443f95afff6de8f1690c77c97d6fc9c9bb2d2cd0662e9ff9f" +checksum = "8eb022374af2f446981254e6bf9efb6e2c9e1a53176d395fca02792fd4435729" [[package]] name = "minimal-lexical" diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 98faacdc1fb59..d2f8ef8eaae7d 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -219,7 +219,7 @@ impl TypedArena { } else { let ptr = self.ptr.get(); // Advance the pointer. - self.ptr.set(self.ptr.get().offset(1)); + self.ptr.set(self.ptr.get().add(1)); // Write into uninitialized memory. ptr::write(ptr, object); &mut *ptr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index d5180b46aaff4..598bf771008db 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -504,7 +504,7 @@ pub struct WhereEqPredicate { #[derive(Clone, Encodable, Decodable, Debug)] pub struct Crate { - pub attrs: Vec, + pub attrs: AttrVec, pub items: Vec>, pub spans: ModSpans, /// Must be equal to `CRATE_NODE_ID` after the crate root is expanded, but may hold @@ -1268,7 +1268,7 @@ impl Expr { id: DUMMY_NODE_ID, kind: ExprKind::Err, span: DUMMY_SP, - attrs: ThinVec::new(), + attrs: AttrVec::new(), tokens: None, }, ) @@ -2669,7 +2669,7 @@ impl VariantData { /// An item definition. #[derive(Clone, Encodable, Decodable, Debug)] pub struct Item { - pub attrs: Vec, + pub attrs: AttrVec, pub id: NodeId, pub span: Span, pub vis: Visibility, @@ -3036,19 +3036,19 @@ mod size_asserts { use super::*; use rustc_data_structures::static_assert_size; // These are in alphabetical order, which is easy to maintain. - static_assert_size!(AssocItem, 120); + static_assert_size!(AssocItem, 104); static_assert_size!(AssocItemKind, 32); static_assert_size!(Attribute, 32); static_assert_size!(Block, 48); static_assert_size!(Expr, 104); static_assert_size!(ExprKind, 72); static_assert_size!(Fn, 192); - static_assert_size!(ForeignItem, 112); + static_assert_size!(ForeignItem, 96); static_assert_size!(ForeignItemKind, 24); static_assert_size!(GenericBound, 88); static_assert_size!(Generics, 72); static_assert_size!(Impl, 200); - static_assert_size!(Item, 200); + static_assert_size!(Item, 184); static_assert_size!(ItemKind, 112); static_assert_size!(Lit, 48); static_assert_size!(LitKind, 24); diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 1fc5e480215ea..0947a71b82432 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -270,7 +270,7 @@ pub trait HasAttrs { /// during token collection. const SUPPORTS_CUSTOM_INNER_ATTRS: bool; fn attrs(&self) -> &[Attribute]; - fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)); + fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)); } macro_rules! impl_has_attrs { @@ -283,8 +283,8 @@ macro_rules! impl_has_attrs { &self.attrs } - fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { - VecOrAttrVec::visit(&mut self.attrs, f) + fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) { + f(&mut self.attrs) } } )+ @@ -299,7 +299,7 @@ macro_rules! impl_has_attrs_none { fn attrs(&self) -> &[Attribute] { &[] } - fn visit_attrs(&mut self, _f: impl FnOnce(&mut Vec)) {} + fn visit_attrs(&mut self, _f: impl FnOnce(&mut AttrVec)) {} } )+ }; @@ -330,7 +330,7 @@ impl> HasAttrs for T { fn attrs(&self) -> &[Attribute] { self.ast_deref().attrs() } - fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { + fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) { self.ast_deref_mut().visit_attrs(f) } } @@ -340,7 +340,7 @@ impl HasAttrs for Option { fn attrs(&self) -> &[Attribute] { self.as_ref().map(|inner| inner.attrs()).unwrap_or(&[]) } - fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { + fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) { if let Some(inner) = self.as_mut() { inner.visit_attrs(f); } @@ -362,13 +362,13 @@ impl HasAttrs for StmtKind { } } - fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { + fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) { match self { - StmtKind::Local(local) => visit_attrvec(&mut local.attrs, f), + StmtKind::Local(local) => f(&mut local.attrs), StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.visit_attrs(f), StmtKind::Item(item) => item.visit_attrs(f), StmtKind::Empty => {} - StmtKind::MacCall(mac) => visit_attrvec(&mut mac.attrs, f), + StmtKind::MacCall(mac) => f(&mut mac.attrs), } } } @@ -378,38 +378,11 @@ impl HasAttrs for Stmt { fn attrs(&self) -> &[Attribute] { self.kind.attrs() } - fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { + fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) { self.kind.visit_attrs(f); } } -/// Helper trait for the impls above. Abstracts over -/// the two types of attribute fields that AST nodes -/// may have (`Vec` or `AttrVec`). -trait VecOrAttrVec { - fn visit(&mut self, f: impl FnOnce(&mut Vec)); -} - -impl VecOrAttrVec for Vec { - fn visit(&mut self, f: impl FnOnce(&mut Vec)) { - f(self) - } -} - -impl VecOrAttrVec for AttrVec { - fn visit(&mut self, f: impl FnOnce(&mut Vec)) { - visit_attrvec(self, f) - } -} - -fn visit_attrvec(attrs: &mut AttrVec, f: impl FnOnce(&mut Vec)) { - crate::mut_visit::visit_clobber(attrs, |attrs| { - let mut vec = attrs.into(); - f(&mut vec); - vec.into() - }); -} - /// A newtype around an AST node that implements the traits above if the node implements them. pub struct AstNodeWrapper { pub wrapped: Wrapped, diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 0d114f1366c4d..5b72ec2b6015c 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -12,7 +12,6 @@ use crate::tokenstream::{DelimSpan, Spacing, TokenTree}; use crate::tokenstream::{LazyTokenStream, TokenStream}; use crate::util::comments; -use rustc_data_structures::thin_vec::ThinVec; use rustc_index::bit_set::GrowableBitSet; use rustc_span::source_map::BytePos; use rustc_span::symbol::{sym, Ident, Symbol}; @@ -487,7 +486,7 @@ impl MetaItemKind { id: ast::DUMMY_NODE_ID, kind: ast::ExprKind::Lit(lit.clone()), span: lit.span, - attrs: ThinVec::new(), + attrs: ast::AttrVec::new(), tokens: None, }); MacArgs::Eq(span, MacArgsEq::Ast(expr)) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 0520319e3be14..458d1156ec251 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -14,7 +14,6 @@ use crate::tokenstream::*; use rustc_data_structures::map_in_place::MapInPlace; use rustc_data_structures::sync::Lrc; -use rustc_data_structures::thin_vec::ThinVec; use rustc_span::source_map::Spanned; use rustc_span::symbol::Ident; use rustc_span::Span; @@ -338,12 +337,7 @@ where } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_attrs(attrs: &mut Vec, vis: &mut T) { - visit_vec(attrs, |attr| vis.visit_attribute(attr)); -} - -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_thin_attrs(attrs: &mut AttrVec, vis: &mut T) { +pub fn visit_attrs(attrs: &mut AttrVec, vis: &mut T) { for attr in attrs.iter_mut() { vis.visit_attribute(attr); } @@ -398,7 +392,7 @@ pub fn noop_flat_map_pat_field( vis.visit_ident(ident); vis.visit_pat(pat); vis.visit_span(span); - visit_thin_attrs(attrs, vis); + visit_attrs(attrs, vis); smallvec![fp] } @@ -424,7 +418,7 @@ pub fn noop_visit_use_tree(use_tree: &mut UseTree, vis: &mut T) { pub fn noop_flat_map_arm(mut arm: Arm, vis: &mut T) -> SmallVec<[Arm; 1]> { let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm; - visit_thin_attrs(attrs, vis); + visit_attrs(attrs, vis); vis.visit_id(id); vis.visit_pat(pat); visit_opt(guard, |guard| vis.visit_expr(guard)); @@ -507,7 +501,7 @@ pub fn noop_flat_map_variant( let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant; visitor.visit_ident(ident); visitor.visit_vis(vis); - visit_thin_attrs(attrs, visitor); + visit_attrs(attrs, visitor); visitor.visit_id(id); visitor.visit_variant_data(data); visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr)); @@ -589,7 +583,7 @@ pub fn noop_visit_local(local: &mut P, vis: &mut T) { } } vis.visit_span(span); - visit_thin_attrs(attrs, vis); + visit_attrs(attrs, vis); visit_lazy_tts(tokens, vis); } @@ -640,7 +634,7 @@ pub fn noop_visit_meta_item(mi: &mut MetaItem, vis: &mut T) { pub fn noop_flat_map_param(mut param: Param, vis: &mut T) -> SmallVec<[Param; 1]> { let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param; vis.visit_id(id); - visit_thin_attrs(attrs, vis); + visit_attrs(attrs, vis); vis.visit_pat(pat); vis.visit_span(span); vis.visit_ty(ty); @@ -882,7 +876,7 @@ pub fn noop_flat_map_generic_param( if let Some(ref mut colon_span) = colon_span { vis.visit_span(colon_span); } - visit_thin_attrs(attrs, vis); + visit_attrs(attrs, vis); visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis)); match kind { GenericParamKind::Lifetime => {} @@ -978,7 +972,7 @@ pub fn noop_flat_map_field_def( visitor.visit_vis(vis); visitor.visit_id(id); visitor.visit_ty(ty); - visit_thin_attrs(attrs, visitor); + visit_attrs(attrs, visitor); smallvec![fd] } @@ -991,7 +985,7 @@ pub fn noop_flat_map_expr_field( vis.visit_expr(expr); vis.visit_id(id); vis.visit_span(span); - visit_thin_attrs(attrs, vis); + visit_attrs(attrs, vis); smallvec![f] } @@ -1432,7 +1426,7 @@ pub fn noop_visit_expr( } vis.visit_id(id); vis.visit_span(span); - visit_thin_attrs(attrs, vis); + visit_attrs(attrs, vis); visit_lazy_tts(tokens, vis); } @@ -1478,7 +1472,7 @@ pub fn noop_flat_map_stmt_kind( StmtKind::MacCall(mut mac) => { let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut(); vis.visit_mac_call(mac_); - visit_thin_attrs(attrs, vis); + visit_attrs(attrs, vis); visit_lazy_tts(tokens, vis); smallvec![StmtKind::MacCall(mac)] } @@ -1513,12 +1507,6 @@ impl DummyAstNode for P { } } -impl DummyAstNode for ThinVec { - fn dummy() -> Self { - Default::default() - } -} - impl DummyAstNode for Item { fn dummy() -> Self { Item { diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 32dbd2ff47d6b..bd61f4fa87ab8 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -6,7 +6,6 @@ use rustc_ast::attr; use rustc_ast::ptr::P as AstP; use rustc_ast::*; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_data_structures::thin_vec::ThinVec; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::Res; @@ -448,12 +447,12 @@ impl<'hir> LoweringContext<'_, 'hir> { let lowered_cond = self.with_loop_condition_scope(|t| t.lower_expr(cond)); let new_cond = self.manage_let_cond(lowered_cond); let then = self.lower_block_expr(body); - let expr_break = self.expr_break(span, ThinVec::new()); + let expr_break = self.expr_break(span, AttrVec::new()); let stmt_break = self.stmt_expr(span, expr_break); let else_blk = self.block_all(span, arena_vec![self; stmt_break], None); - let else_expr = self.arena.alloc(self.expr_block(else_blk, ThinVec::new())); + let else_expr = self.arena.alloc(self.expr_block(else_blk, AttrVec::new())); let if_kind = hir::ExprKind::If(new_cond, self.arena.alloc(then), Some(else_expr)); - let if_expr = self.expr(span, if_kind, ThinVec::new()); + let if_expr = self.expr(span, if_kind, AttrVec::new()); let block = self.block_expr(self.arena.alloc(if_expr)); let span = self.lower_span(span.with_hi(cond.span.hi())); let opt_label = self.lower_label(opt_label); @@ -512,7 +511,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let constructor = self.arena.alloc(self.expr_lang_item_path( method_span, lang_item, - ThinVec::new(), + AttrVec::new(), None, )); self.expr_call(overall_span, constructor, std::slice::from_ref(expr)) @@ -635,7 +634,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let gen_future = self.expr_lang_item_path( unstable_span, hir::LangItem::FromGenerator, - ThinVec::new(), + AttrVec::new(), None, ); @@ -747,7 +746,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let break_x = self.with_loop_scope(loop_node_id, move |this| { let expr_break = hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr)); - this.arena.alloc(this.expr(gen_future_span, expr_break, ThinVec::new())) + this.arena.alloc(this.expr(gen_future_span, expr_break, AttrVec::new())) }); self.arm(ready_pat, break_x) }; @@ -780,7 +779,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let yield_expr = self.expr( span, hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }), - ThinVec::new(), + AttrVec::new(), ); let yield_expr = self.arena.alloc(yield_expr); @@ -987,7 +986,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::AsyncGeneratorKind::Closure, |this| this.with_new_scopes(|this| this.lower_expr_mut(body)), ); - this.expr(fn_decl_span, async_body, ThinVec::new()) + this.expr(fn_decl_span, async_body, AttrVec::new()) }); body_id }); @@ -1257,7 +1256,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let ident = self.expr_ident(lhs.span, ident, binding); let assign = hir::ExprKind::Assign(self.lower_expr(lhs), ident, self.lower_span(eq_sign_span)); - let expr = self.expr(lhs.span, assign, ThinVec::new()); + let expr = self.expr(lhs.span, assign, AttrVec::new()); assignments.push(self.stmt_expr(lhs.span, expr)); pat } @@ -1299,7 +1298,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let fn_path = hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None); let fn_expr = - self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new())); + self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), AttrVec::new())); hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2]) } @@ -1472,7 +1471,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // `None => break` let none_arm = { let break_expr = - self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span, ThinVec::new())); + self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span, AttrVec::new())); let pat = self.pat_none(for_span); self.arm(pat, break_expr) }; @@ -1481,7 +1480,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let some_arm = { let some_pat = self.pat_some(pat_span, pat); let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false)); - let body_expr = self.arena.alloc(self.expr_block(body_block, ThinVec::new())); + let body_expr = self.arena.alloc(self.expr_block(body_block, AttrVec::new())); self.arm(some_pat, body_expr) }; @@ -1596,7 +1595,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }; attr::mk_attr_outer(allow) }; - let attrs = vec![attr]; + let attrs: AttrVec = vec![attr].into(); // `ControlFlow::Continue(val) => #[allow(unreachable_code)] val,` let continue_arm = { @@ -1606,7 +1605,7 @@ impl<'hir> LoweringContext<'_, 'hir> { span, val_ident, val_pat_nid, - ThinVec::from(attrs.clone()), + attrs.clone(), )); let continue_pat = self.pat_cf_continue(unstable_span, val_pat); self.arm(continue_pat, val_expr) @@ -1625,7 +1624,6 @@ impl<'hir> LoweringContext<'_, 'hir> { self.arena.alloc(residual_expr), unstable_span, ); - let thin_attrs = ThinVec::from(attrs); let ret_expr = if let Some(catch_node) = self.catch_scope { let target_id = Ok(self.lower_node_id(catch_node)); self.arena.alloc(self.expr( @@ -1634,13 +1632,13 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::Destination { label: None, target_id }, Some(from_residual_expr), ), - thin_attrs, + attrs, )) } else { self.arena.alloc(self.expr( try_span, hir::ExprKind::Ret(Some(from_residual_expr)), - thin_attrs, + attrs, )) }; @@ -1728,7 +1726,7 @@ impl<'hir> LoweringContext<'_, 'hir> { arms: &'hir [hir::Arm<'hir>], source: hir::MatchSource, ) -> hir::Expr<'hir> { - self.expr(span, hir::ExprKind::Match(arg, arms, source), ThinVec::new()) + self.expr(span, hir::ExprKind::Match(arg, arms, source), AttrVec::new()) } fn expr_break(&mut self, span: Span, attrs: AttrVec) -> hir::Expr<'hir> { @@ -1745,12 +1743,12 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr( span, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e), - ThinVec::new(), + AttrVec::new(), ) } fn expr_unit(&mut self, sp: Span) -> &'hir hir::Expr<'hir> { - self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), ThinVec::new())) + self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), AttrVec::new())) } fn expr_call_mut( @@ -1759,7 +1757,7 @@ impl<'hir> LoweringContext<'_, 'hir> { e: &'hir hir::Expr<'hir>, args: &'hir [hir::Expr<'hir>], ) -> hir::Expr<'hir> { - self.expr(span, hir::ExprKind::Call(e, args), ThinVec::new()) + self.expr(span, hir::ExprKind::Call(e, args), AttrVec::new()) } fn expr_call( @@ -1779,7 +1777,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir_id: Option, ) -> hir::Expr<'hir> { let path = - self.arena.alloc(self.expr_lang_item_path(span, lang_item, ThinVec::new(), hir_id)); + self.arena.alloc(self.expr_lang_item_path(span, lang_item, AttrVec::new(), hir_id)); self.expr_call_mut(span, path, args) } @@ -1822,7 +1820,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ident: Ident, binding: hir::HirId, ) -> hir::Expr<'hir> { - self.expr_ident_with_attrs(sp, ident, binding, ThinVec::new()) + self.expr_ident_with_attrs(sp, ident, binding, AttrVec::new()) } fn expr_ident_with_attrs( @@ -1860,13 +1858,13 @@ impl<'hir> LoweringContext<'_, 'hir> { }), None, ), - ThinVec::new(), + AttrVec::new(), ) } fn expr_block_empty(&mut self, span: Span) -> &'hir hir::Expr<'hir> { let blk = self.block_all(span, &[], None); - let expr = self.expr_block(blk, ThinVec::new()); + let expr = self.expr_block(blk, AttrVec::new()); self.arena.alloc(expr) } diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index d28187dc42de4..6894ec7956cfe 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -854,7 +854,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ident.span, "calling this method introduces the `impl`'s 'static` requirement", ); - // TODO! err.span_note(multi_span, "the used `impl` has a `'static` requirement"); err.span_suggestion_verbose( span.shrink_to_hi(), diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 2828b972c5f99..78c817150a65a 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -50,6 +50,8 @@ use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveData, MoveE use rustc_mir_dataflow::Analysis; use rustc_mir_dataflow::MoveDataParamEnv; +use crate::session_diagnostics::VarNeedNotMut; + use self::diagnostics::{AccessKind, RegionName}; use self::location::LocationTable; use self::prefixes::PrefixSet; @@ -424,12 +426,7 @@ fn do_mir_borrowck<'a, 'tcx>( continue; } - tcx.emit_spanned_lint( - UNUSED_MUT, - lint_root, - span, - session_diagnostics::VarBetterNotMut { span }, - ) + tcx.emit_spanned_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span }) } let tainted_by_errors = mbcx.emit_errors(); diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index b0d7253651b09..127cb4e408372 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -641,7 +641,6 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { Some(GenericArgKind::Const(c1)) => c1, Some(u) => panic!("const mapped to unexpected kind: {:?}", u), None => { - //FIXME! self.tcx.sess.emit_err(ConstNotUsedTraitAlias { ct: ct.to_string(), span: self.span, diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 3a24b28da3556..ff2196760039c 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -1,18 +1,9 @@ -use rustc_errors::MultiSpan; use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_middle::ty::Ty; use rustc_span::Span; #[derive(SessionDiagnostic)] -#[error(borrowck::move_borrowed, code = "E0505")] -pub(crate) struct MoveBorrowed<'cx> { - #[primary_span] - pub span: Span, - pub desc: &'cx str, -} - -#[derive(SessionDiagnostic)] -#[error(borrowck::move_unsized, code = "E0161")] +#[diag(borrowck::move_unsized, code = "E0161")] pub(crate) struct MoveUnsized<'tcx> { pub ty: Ty<'tcx>, #[primary_span] @@ -21,7 +12,7 @@ pub(crate) struct MoveUnsized<'tcx> { } #[derive(SessionDiagnostic)] -#[error(borrowck::higher_ranked_lifetime_error)] +#[diag(borrowck::higher_ranked_lifetime_error)] pub(crate) struct HigherRankedLifetimeError { #[subdiagnostic] pub cause: Option, @@ -38,14 +29,14 @@ pub(crate) enum HigherRankedErrorCause { } #[derive(SessionDiagnostic)] -#[error(borrowck::higher_ranked_subtype_error)] +#[diag(borrowck::higher_ranked_subtype_error)] pub(crate) struct HigherRankedSubtypeError { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(borrowck::generic_does_not_live_long_enough)] +#[diag(borrowck::generic_does_not_live_long_enough)] pub(crate) struct GenericDoesNotLiveLongEnough { pub kind: String, #[primary_span] @@ -53,14 +44,14 @@ pub(crate) struct GenericDoesNotLiveLongEnough { } #[derive(LintDiagnostic)] -#[lint(borrowck::var_better_not_mut)] -pub(crate) struct VarBetterNotMut { +#[diag(borrowck::var_does_not_need_mut)] +pub(crate) struct VarNeedNotMut { #[suggestion_short(applicability = "machine-applicable", code = "")] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(borrowck::const_not_used_in_type_alias)] +#[diag(borrowck::const_not_used_in_type_alias)] pub(crate) struct ConstNotUsedTraitAlias { pub ct: String, #[primary_span] @@ -68,7 +59,7 @@ pub(crate) struct ConstNotUsedTraitAlias { } #[derive(SessionDiagnostic)] -#[error(borrowck::var_cannot_escape_closure)] +#[diag(borrowck::var_cannot_escape_closure)] #[note] #[note(borrowck::cannot_escape)] pub(crate) struct FnMutError { @@ -104,7 +95,7 @@ pub(crate) enum FnMutReturnTypeErr { } #[derive(SessionDiagnostic)] -#[error(borrowck::lifetime_constraints_error)] +#[diag(borrowck::lifetime_constraints_error)] pub(crate) struct LifeTimeOutLiveErr { #[primary_span] pub span: Span, @@ -131,12 +122,3 @@ pub(crate) enum LifeTimeReturnCategoryErr { outlived_fr_name: String, }, } - -#[derive(SessionSubdiagnostic)] -pub(crate) enum StaticLifeTimeRequireErr { - #[note(borrowck::impl_require_static)] - UsedImpl { - #[primary_span] - span: MultiSpan, - }, -} diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 6cfe5efb68886..451b82c5c1870 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -90,12 +90,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { locations: Locations, category: ConstraintCategory<'tcx>, ) { - self.prove_predicates( - Some(ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate { + self.prove_predicate( + ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, constness: ty::BoundConstness::NotConst, polarity: ty::ImplPolarity::Positive, - }))), + })) + .to_predicate(self.tcx()), locations, category, ); diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 74655369faf03..bb28622edf931 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -268,7 +268,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { // } // impl Foo for () { // type Bar = (); - // fn foo(&self) ->&() {} + // fn foo(&self) -> &() {} // } // ``` // Both &Self::Bar and &() are WF diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 7bf7f7357bf4f..293d847ec9ab7 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -178,97 +178,15 @@ pub(crate) fn type_check<'mir, 'tcx>( upvars, }; - let opaque_type_values = type_check_internal( + let mut checker = TypeChecker::new( infcx, - param_env, body, - promoted, + param_env, ®ion_bound_pairs, implicit_region_bound, &mut borrowck_context, - |mut cx| { - debug!("inside extra closure of type_check_internal"); - cx.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output); - liveness::generate( - &mut cx, - body, - elements, - flow_inits, - move_data, - location_table, - use_polonius, - ); - - translate_outlives_facts(&mut cx); - let opaque_type_values = - infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); - - opaque_type_values - .into_iter() - .map(|(opaque_type_key, decl)| { - cx.fully_perform_op( - Locations::All(body.span), - ConstraintCategory::OpaqueType, - CustomTypeOp::new( - |infcx| { - infcx.register_member_constraints( - param_env, - opaque_type_key, - decl.hidden_type.ty, - decl.hidden_type.span, - ); - Ok(InferOk { value: (), obligations: vec![] }) - }, - || "opaque_type_map".to_string(), - ), - ) - .unwrap(); - let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type); - trace!( - "finalized opaque type {:?} to {:#?}", - opaque_type_key, - hidden_type.ty.kind() - ); - if hidden_type.has_infer_types_or_consts() { - infcx.tcx.sess.delay_span_bug( - decl.hidden_type.span, - &format!("could not resolve {:#?}", hidden_type.ty.kind()), - ); - hidden_type.ty = infcx.tcx.ty_error(); - } - - (opaque_type_key, (hidden_type, decl.origin)) - }) - .collect() - }, ); - MirTypeckResults { constraints, universal_region_relations, opaque_type_values } -} - -#[instrument( - skip(infcx, body, promoted, region_bound_pairs, borrowck_context, extra), - level = "debug" -)] -fn type_check_internal<'a, 'tcx, R>( - infcx: &'a InferCtxt<'a, 'tcx>, - param_env: ty::ParamEnv<'tcx>, - body: &'a Body<'tcx>, - promoted: &'a IndexVec>, - region_bound_pairs: &'a RegionBoundPairs<'tcx>, - implicit_region_bound: ty::Region<'tcx>, - borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, - extra: impl FnOnce(TypeChecker<'a, 'tcx>) -> R, -) -> R { - debug!("body: {:#?}", body); - let mut checker = TypeChecker::new( - infcx, - body, - param_env, - region_bound_pairs, - implicit_region_bound, - borrowck_context, - ); let errors_reported = { let mut verifier = TypeVerifier::new(&mut checker, promoted); verifier.visit_body(&body); @@ -280,7 +198,56 @@ fn type_check_internal<'a, 'tcx, R>( checker.typeck_mir(body); } - extra(checker) + checker.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output); + liveness::generate( + &mut checker, + body, + elements, + flow_inits, + move_data, + location_table, + use_polonius, + ); + + translate_outlives_facts(&mut checker); + let opaque_type_values = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); + + let opaque_type_values = opaque_type_values + .into_iter() + .map(|(opaque_type_key, decl)| { + checker + .fully_perform_op( + Locations::All(body.span), + ConstraintCategory::OpaqueType, + CustomTypeOp::new( + |infcx| { + infcx.register_member_constraints( + param_env, + opaque_type_key, + decl.hidden_type.ty, + decl.hidden_type.span, + ); + Ok(InferOk { value: (), obligations: vec![] }) + }, + || "opaque_type_map".to_string(), + ), + ) + .unwrap(); + let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type); + trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind()); + if hidden_type.has_infer_types_or_consts() { + infcx.tcx.sess.delay_span_bug( + decl.hidden_type.span, + &format!("could not resolve {:#?}", hidden_type.ty.kind()), + ); + hidden_type.ty = infcx.tcx.ty_error(); + } + + (opaque_type_key, (hidden_type, decl.origin)) + }) + .collect(); + + MirTypeckResults { constraints, universal_region_relations, opaque_type_values } } fn translate_outlives_facts(typeck: &mut TypeChecker<'_, '_>) { @@ -1911,7 +1878,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - &Rvalue::NullaryOp(_, ty) => { + &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => { let trait_ref = ty::TraitRef { def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), substs: tcx.mk_substs_trait(ty, &[]), diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 1a0ea8f416064..a1051d990b14b 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -852,7 +852,7 @@ pub(super) fn expand_global_asm<'cx>( if let Some(inline_asm) = expand_preparsed_asm(ecx, args) { MacEager::items(smallvec![P(ast::Item { ident: Ident::empty(), - attrs: Vec::new(), + attrs: ast::AttrVec::new(), id: ast::DUMMY_NODE_ID, kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)), vis: ast::Visibility { diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index d30fd479015ff..d2ee4249989ee 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -119,7 +119,8 @@ impl<'cx, 'a> Context<'cx, 'a> { vec![self.cx.attribute(attr::mk_list_item( Ident::new(sym::allow, self.span), vec![attr::mk_nested_word_item(Ident::new(sym::unused_imports, self.span))], - ))], + ))] + .into(), ItemKind::Use(UseTree { prefix: self.cx.path(self.span, self.cx.std_path(&[sym::asserting])), kind: UseTreeKind::Nested(vec![ diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index aa355150b4f81..9046bf1305933 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -36,7 +36,7 @@ pub fn expand_cfg( } #[derive(SessionDiagnostic)] -#[error(builtin_macros::requires_cfg_pattern)] +#[diag(builtin_macros::requires_cfg_pattern)] struct RequiresCfgPattern { #[primary_span] #[label] @@ -44,7 +44,7 @@ struct RequiresCfgPattern { } #[derive(SessionDiagnostic)] -#[error(builtin_macros::expected_one_cfg_pattern)] +#[diag(builtin_macros::expected_one_cfg_pattern)] struct OneCfgPattern { #[primary_span] span: Span, diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index ee4c5aea1a352..dd7989cf48c37 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -68,7 +68,7 @@ pub fn expand_deriving_clone( } let inline = cx.meta_word(span, sym::inline); - let attrs = vec![cx.attribute(inline)]; + let attrs = vec![cx.attribute(inline)].into(); let trait_def = TraitDef { span, path: path_std!(clone::Clone), diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs index f99ee8cb2d53c..9b6d3e5032f94 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs @@ -20,7 +20,7 @@ pub fn expand_deriving_eq( let hidden = rustc_ast::attr::mk_nested_word_item(Ident::new(sym::hidden, span)); let doc = rustc_ast::attr::mk_list_item(Ident::new(sym::doc, span), vec![hidden]); let no_coverage = cx.meta_word(span, sym::no_coverage); - let attrs = vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)]; + let attrs = vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)].into(); let trait_def = TraitDef { span, path: path_std!(cmp::Eq), diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs index 8aa16dfeb0f1f..0e17b95178759 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs @@ -15,7 +15,7 @@ pub fn expand_deriving_ord( push: &mut dyn FnMut(Annotatable), ) { let inline = cx.meta_word(span, sym::inline); - let attrs = vec![cx.attribute(inline)]; + let attrs = vec![cx.attribute(inline)].into(); let trait_def = TraitDef { span, path: path_std!(cmp::Ord), diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs index 6f86092ba491b..ac1325b92a6f3 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs @@ -68,7 +68,7 @@ pub fn expand_deriving_partial_eq( // No need to generate `ne`, the default suffices, and not generating it is // faster. let inline = cx.meta_word(span, sym::inline); - let attrs = vec![cx.attribute(inline)]; + let attrs = vec![cx.attribute(inline)].into(); let methods = vec![MethodDef { name: sym::eq, generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs index 137c779f81b84..7763e55401783 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs @@ -19,7 +19,7 @@ pub fn expand_deriving_partial_ord( Path(Path::new_(pathvec_std!(option::Option), vec![Box::new(ordering_ty)], PathKind::Std)); let inline = cx.meta_word(span, sym::inline); - let attrs = vec![cx.attribute(inline)]; + let attrs = vec![cx.attribute(inline)].into(); let partial_cmp_def = MethodDef { name: sym::partial_cmp, diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index f82175af4f6f2..4af7fd8165388 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -29,7 +29,7 @@ pub fn expand_deriving_debug( explicit_self: true, nonself_args: vec![(fmtr, sym::f)], ret_ty: Path(path_std!(fmt::Result)), - attributes: Vec::new(), + attributes: ast::AttrVec::new(), unify_fieldless_variants: false, combine_substructure: combine_substructure(Box::new(|a, b, c| { show_substructure(a, b, c) diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs index 47da0862b52fc..7174dbbe7ea8b 100644 --- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs @@ -47,7 +47,7 @@ pub fn expand_deriving_rustc_decodable( ], PathKind::Std, )), - attributes: Vec::new(), + attributes: ast::AttrVec::new(), unify_fieldless_variants: false, combine_substructure: combine_substructure(Box::new(|a, b, c| { decodable_substructure(a, b, c, krate) diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index a431832080c0c..f316f01ef6615 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -2,9 +2,7 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use rustc_ast as ast; -use rustc_ast::walk_list; -use rustc_ast::EnumDef; -use rustc_ast::VariantData; +use rustc_ast::{walk_list, EnumDef, VariantData}; use rustc_errors::Applicability; use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt}; use rustc_span::symbol::Ident; @@ -22,7 +20,7 @@ pub fn expand_deriving_default( item.visit_with(&mut DetectNonVariantDefaultAttr { cx }); let inline = cx.meta_word(span, sym::inline); - let attrs = vec![cx.attribute(inline)]; + let attrs = vec![cx.attribute(inline)].into(); let trait_def = TraitDef { span, path: Path::new(vec![kw::Default, sym::Default]), diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs index d43c66a5fa644..b220e54238f46 100644 --- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs @@ -89,7 +89,7 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::pathvec_std; -use rustc_ast::{ExprKind, MetaItem, Mutability}; +use rustc_ast::{AttrVec, ExprKind, MetaItem, Mutability}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; @@ -131,7 +131,7 @@ pub fn expand_deriving_rustc_encodable( ], PathKind::Std, )), - attributes: Vec::new(), + attributes: AttrVec::new(), unify_fieldless_variants: false, combine_substructure: combine_substructure(Box::new(|a, b, c| { encodable_substructure(a, b, c, krate) diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index a39b97d07ef0a..c1bbc601560fa 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -217,7 +217,7 @@ pub struct MethodDef<'a> { /// Returns type pub ret_ty: Ty, - pub attributes: Vec, + pub attributes: ast::AttrVec, /// Can we combine fieldless variants for enums into a single match arm? /// If true, indicates that the trait operation uses the enum tag in some @@ -562,7 +562,7 @@ impl<'a> TraitDef<'a> { kind: ast::VisibilityKind::Inherited, tokens: None, }, - attrs: Vec::new(), + attrs: ast::AttrVec::new(), kind: ast::AssocItemKind::TyAlias(Box::new(ast::TyAlias { defaultness: ast::Defaultness::Final, generics: Generics::default(), @@ -716,7 +716,7 @@ impl<'a> TraitDef<'a> { let self_type = cx.ty_path(path); let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived)); - let attrs = vec![attr]; + let attrs = vec![attr].into(); let opt_trait_ref = Some(trait_ref); cx.item( diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 9aa170bec14d8..f1f02e7ce7787 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -2,7 +2,7 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::{path_std, pathvec_std}; -use rustc_ast::{MetaItem, Mutability}; +use rustc_ast::{AttrVec, MetaItem, Mutability}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; @@ -31,7 +31,7 @@ pub fn expand_deriving_hash( explicit_self: true, nonself_args: vec![(Ref(Box::new(Path(arg)), Mutability::Mut), sym::state)], ret_ty: Unit, - attributes: vec![], + attributes: AttrVec::new(), unify_fieldless_variants: true, combine_substructure: combine_substructure(Box::new(|a, b, c| { hash_substructure(a, b, c) diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index c1ca089da221f..a65d0bad6de80 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -164,7 +164,7 @@ fn inject_impl_of_structural_trait( // Keep the lint and stability attributes of the original item, to control // how the generated implementation is linted. - let mut attrs = Vec::new(); + let mut attrs = ast::AttrVec::new(); attrs.extend( item.attrs .iter() diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index 36cfbba45dacc..2bad9bbce6650 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -4,7 +4,7 @@ use rustc_ast::expand::allocator::{ AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS, }; use rustc_ast::ptr::P; -use rustc_ast::{self as ast, Attribute, Expr, FnHeader, FnSig, Generics, Param, StmtKind}; +use rustc_ast::{self as ast, AttrVec, Expr, FnHeader, FnSig, Generics, Param, StmtKind}; use rustc_ast::{Fn, ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -113,10 +113,10 @@ impl AllocFnFactory<'_, '_> { self.cx.expr_call(self.ty_span, method, args) } - fn attrs(&self) -> Vec { + fn attrs(&self) -> AttrVec { let special = sym::rustc_std_internal_symbol; let special = self.cx.meta_word(self.span, special); - vec![self.cx.attribute(special)] + vec![self.cx.attribute(special)].into() } fn arg_ty( diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index 5cfda33491d5b..ebe1c3663e3a7 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -281,7 +281,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P { let span = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id()); let proc_macro = Ident::new(sym::proc_macro, span); - let krate = cx.item(span, proc_macro, Vec::new(), ast::ItemKind::ExternCrate(None)); + let krate = cx.item(span, proc_macro, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None)); let bridge = Ident::new(sym::bridge, span); let client = Ident::new(sym::client, span); diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs index 09ad5f9b3eaa9..90ea1e457ba80 100644 --- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs +++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs @@ -51,7 +51,7 @@ pub fn inject( cx.item( span, ident, - vec![cx.attribute(cx.meta_word(span, sym::macro_use))], + vec![cx.attribute(cx.meta_word(span, sym::macro_use))].into(), ast::ItemKind::ExternCrate(None), ), ); @@ -78,7 +78,7 @@ pub fn inject( let use_item = cx.item( span, Ident::empty(), - vec![cx.attribute(cx.meta_word(span, sym::prelude_import))], + vec![cx.attribute(cx.meta_word(span, sym::prelude_import))].into(), ast::ItemKind::Use(ast::UseTree { prefix: cx.path(span, import_path), kind: ast::UseTreeKind::Glob, diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index e20375689f3d1..03c84f5ec2a74 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -227,7 +227,8 @@ pub fn expand_test_or_bench( )), // #[rustc_test_marker] cx.attribute(cx.meta_word(attr_sp, sym::rustc_test_marker)), - ], + ] + .into(), // const $ident: test::TestDescAndFn = ast::ItemKind::Const( ast::Defaultness::Final, @@ -334,7 +335,7 @@ pub fn expand_test_or_bench( }); // extern crate test - let test_extern = cx.item(sp, test_id, vec![], ast::ItemKind::ExternCrate(None)); + let test_extern = cx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None)); tracing::debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const)); diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 0ebe29df95f20..093f0f10a3867 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -298,8 +298,10 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P { let call_test_main = ecx.stmt_expr(call_test_main); // extern crate test - let test_extern_stmt = - ecx.stmt_item(sp, ecx.item(sp, test_id, vec![], ast::ItemKind::ExternCrate(None))); + let test_extern_stmt = ecx.stmt_item( + sp, + ecx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None)), + ); // #[rustc_main] let main_meta = ecx.meta_word(sp, sym::rustc_main); @@ -333,7 +335,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P { let main = P(ast::Item { ident: main_id, - attrs: vec![main_attr], + attrs: vec![main_attr].into(), id: ast::DUMMY_NODE_ID, kind: main, vis: ast::Visibility { span: sp, kind: ast::VisibilityKind::Public, tokens: None }, diff --git a/compiler/rustc_codegen_cranelift/example/alloc_system.rs b/compiler/rustc_codegen_cranelift/example/alloc_system.rs index cf95c89bc3156..50261c1939739 100644 --- a/compiler/rustc_codegen_cranelift/example/alloc_system.rs +++ b/compiler/rustc_codegen_cranelift/example/alloc_system.rs @@ -94,7 +94,7 @@ mod platform { struct Header(*mut u8); const HEAP_ZERO_MEMORY: DWORD = 0x00000008; unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header { - &mut *(ptr as *mut Header).offset(-1) + &mut *(ptr as *mut Header).sub(1) } unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 { let aligned = ptr.add(align - (ptr as usize & (align - 1))); diff --git a/compiler/rustc_codegen_gcc/example/alloc_system.rs b/compiler/rustc_codegen_gcc/example/alloc_system.rs index 5f66ca67f2d40..89661918d05a5 100644 --- a/compiler/rustc_codegen_gcc/example/alloc_system.rs +++ b/compiler/rustc_codegen_gcc/example/alloc_system.rs @@ -156,7 +156,7 @@ mod platform { struct Header(*mut u8); const HEAP_ZERO_MEMORY: DWORD = 0x00000008; unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header { - &mut *(ptr as *mut Header).offset(-1) + &mut *(ptr as *mut Header).sub(1) } unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 { let aligned = ptr.add(align - (ptr as usize & (align - 1))); diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index a463fe7b970f4..01619dee0e42f 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -3,7 +3,7 @@ use rustc_macros::SessionDiagnostic; use rustc_span::Span; #[derive(SessionDiagnostic)] -#[error(const_eval::unstable_in_stable)] +#[diag(const_eval::unstable_in_stable)] pub(crate) struct UnstableInStable { pub gate: String, #[primary_span] @@ -22,14 +22,14 @@ pub(crate) struct UnstableInStable { } #[derive(SessionDiagnostic)] -#[error(const_eval::thread_local_access, code = "E0625")] +#[diag(const_eval::thread_local_access, code = "E0625")] pub(crate) struct NonConstOpErr { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(const_eval::static_access, code = "E0013")] +#[diag(const_eval::static_access, code = "E0013")] #[help] pub(crate) struct StaticAccessErr { #[primary_span] @@ -41,7 +41,7 @@ pub(crate) struct StaticAccessErr { } #[derive(SessionDiagnostic)] -#[error(const_eval::raw_ptr_to_int)] +#[diag(const_eval::raw_ptr_to_int)] #[note] #[note(const_eval::note2)] pub(crate) struct RawPtrToIntErr { @@ -50,7 +50,7 @@ pub(crate) struct RawPtrToIntErr { } #[derive(SessionDiagnostic)] -#[error(const_eval::raw_ptr_comparison)] +#[diag(const_eval::raw_ptr_comparison)] #[note] pub(crate) struct RawPtrComparisonErr { #[primary_span] @@ -58,14 +58,14 @@ pub(crate) struct RawPtrComparisonErr { } #[derive(SessionDiagnostic)] -#[error(const_eval::panic_non_str)] +#[diag(const_eval::panic_non_str)] pub(crate) struct PanicNonStrErr { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(const_eval::mut_deref, code = "E0658")] +#[diag(const_eval::mut_deref, code = "E0658")] pub(crate) struct MutDerefErr { #[primary_span] pub span: Span, @@ -73,7 +73,7 @@ pub(crate) struct MutDerefErr { } #[derive(SessionDiagnostic)] -#[error(const_eval::transient_mut_borrow, code = "E0658")] +#[diag(const_eval::transient_mut_borrow, code = "E0658")] pub(crate) struct TransientMutBorrowErr { #[primary_span] pub span: Span, @@ -81,7 +81,7 @@ pub(crate) struct TransientMutBorrowErr { } #[derive(SessionDiagnostic)] -#[error(const_eval::transient_mut_borrow_raw, code = "E0658")] +#[diag(const_eval::transient_mut_borrow_raw, code = "E0658")] pub(crate) struct TransientMutBorrowErrRaw { #[primary_span] pub span: Span, diff --git a/compiler/rustc_data_structures/src/map_in_place.rs b/compiler/rustc_data_structures/src/map_in_place.rs index 874de03d37ac6..d912211443a89 100644 --- a/compiler/rustc_data_structures/src/map_in_place.rs +++ b/compiler/rustc_data_structures/src/map_in_place.rs @@ -1,3 +1,4 @@ +use crate::thin_vec::ThinVec; use smallvec::{Array, SmallVec}; use std::ptr; @@ -15,94 +16,64 @@ pub trait MapInPlace: Sized { I: IntoIterator; } -impl MapInPlace for Vec { - fn flat_map_in_place(&mut self, mut f: F) - where - F: FnMut(T) -> I, - I: IntoIterator, - { - let mut read_i = 0; - let mut write_i = 0; - unsafe { - let mut old_len = self.len(); - self.set_len(0); // make sure we just leak elements in case of panic +// The implementation of this method is syntactically identical for all the +// different vector types. +macro_rules! flat_map_in_place { + () => { + fn flat_map_in_place(&mut self, mut f: F) + where + F: FnMut(T) -> I, + I: IntoIterator, + { + let mut read_i = 0; + let mut write_i = 0; + unsafe { + let mut old_len = self.len(); + self.set_len(0); // make sure we just leak elements in case of panic - while read_i < old_len { - // move the read_i'th item out of the vector and map it - // to an iterator - let e = ptr::read(self.as_ptr().add(read_i)); - let iter = f(e).into_iter(); - read_i += 1; + while read_i < old_len { + // move the read_i'th item out of the vector and map it + // to an iterator + let e = ptr::read(self.as_ptr().add(read_i)); + let iter = f(e).into_iter(); + read_i += 1; - for e in iter { - if write_i < read_i { - ptr::write(self.as_mut_ptr().add(write_i), e); - write_i += 1; - } else { - // If this is reached we ran out of space - // in the middle of the vector. - // However, the vector is in a valid state here, - // so we just do a somewhat inefficient insert. - self.set_len(old_len); - self.insert(write_i, e); + for e in iter { + if write_i < read_i { + ptr::write(self.as_mut_ptr().add(write_i), e); + write_i += 1; + } else { + // If this is reached we ran out of space + // in the middle of the vector. + // However, the vector is in a valid state here, + // so we just do a somewhat inefficient insert. + self.set_len(old_len); + self.insert(write_i, e); - old_len = self.len(); - self.set_len(0); + old_len = self.len(); + self.set_len(0); - read_i += 1; - write_i += 1; + read_i += 1; + write_i += 1; + } } } - } - // write_i tracks the number of actually written new items. - self.set_len(write_i); + // write_i tracks the number of actually written new items. + self.set_len(write_i); + } } - } + }; } -impl> MapInPlace for SmallVec { - fn flat_map_in_place(&mut self, mut f: F) - where - F: FnMut(T) -> I, - I: IntoIterator, - { - let mut read_i = 0; - let mut write_i = 0; - unsafe { - let mut old_len = self.len(); - self.set_len(0); // make sure we just leak elements in case of panic - - while read_i < old_len { - // move the read_i'th item out of the vector and map it - // to an iterator - let e = ptr::read(self.as_ptr().add(read_i)); - let iter = f(e).into_iter(); - read_i += 1; - - for e in iter { - if write_i < read_i { - ptr::write(self.as_mut_ptr().add(write_i), e); - write_i += 1; - } else { - // If this is reached we ran out of space - // in the middle of the vector. - // However, the vector is in a valid state here, - // so we just do a somewhat inefficient insert. - self.set_len(old_len); - self.insert(write_i, e); - - old_len = self.len(); - self.set_len(0); +impl MapInPlace for Vec { + flat_map_in_place!(); +} - read_i += 1; - write_i += 1; - } - } - } +impl> MapInPlace for SmallVec { + flat_map_in_place!(); +} - // write_i tracks the number of actually written new items. - self.set_len(write_i); - } - } +impl MapInPlace for ThinVec { + flat_map_in_place!(); } diff --git a/compiler/rustc_data_structures/src/thin_vec.rs b/compiler/rustc_data_structures/src/thin_vec.rs index 716259142d18b..fce42e709ab74 100644 --- a/compiler/rustc_data_structures/src/thin_vec.rs +++ b/compiler/rustc_data_structures/src/thin_vec.rs @@ -27,6 +27,51 @@ impl ThinVec { ThinVec(None) => *self = vec![item].into(), } } + + /// Note: if `set_len(0)` is called on a non-empty `ThinVec`, it will + /// remain in the `Some` form. This is required for some code sequences + /// (such as the one in `flat_map_in_place`) that call `set_len(0)` before + /// an operation that might panic, and then call `set_len(n)` again + /// afterwards. + pub unsafe fn set_len(&mut self, new_len: usize) { + match *self { + ThinVec(None) => { + // A prerequisite of `Vec::set_len` is that `new_len` must be + // less than or equal to capacity(). The same applies here. + if new_len != 0 { + panic!("unsafe ThinVec::set_len({})", new_len); + } + } + ThinVec(Some(ref mut vec)) => vec.set_len(new_len), + } + } + + pub fn insert(&mut self, index: usize, value: T) { + match *self { + ThinVec(None) => { + if index == 0 { + *self = vec![value].into(); + } else { + panic!("invalid ThinVec::insert"); + } + } + ThinVec(Some(ref mut vec)) => vec.insert(index, value), + } + } + + pub fn remove(&mut self, index: usize) -> T { + match self { + ThinVec(None) => panic!("invalid ThinVec::remove"), + ThinVec(Some(vec)) => vec.remove(index), + } + } + + pub fn as_slice(&self) -> &[T] { + match self { + ThinVec(None) => &[], + ThinVec(Some(vec)) => vec.as_slice(), + } + } } impl From> for ThinVec { diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 94639bf8e1ee4..dac8df7dc55e0 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1070,7 +1070,7 @@ pub fn handle_options(args: &[String]) -> Option { Some(matches) } -fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, Vec> { +fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::AttrVec> { match input { Input::File(ifile) => rustc_parse::parse_crate_attrs_from_file(ifile, &sess.parse_sess), Input::Str { name, input } => rustc_parse::parse_crate_attrs_from_source_str( diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index 02db2fae7c46e..d89053a99d277 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -13,21 +13,21 @@ borrowck_could_not_normalize = borrowck_higher_ranked_subtype_error = higher-ranked subtype error - -generic_does_not_live_long_enough = + +borrowck_generic_does_not_live_long_enough = `{$kind}` does not live long enough - -borrowck_move_borrowed = + +borrowck_move_borrowed = cannot move out of `{$desc}` beacause it is borrowed - -borrowck_var_better_not_mut = + +borrowck_var_does_not_need_mut = variable does not need to be mutable .suggestion = remove this `mut` -borrowck_const_not_used_in_type_alias = +borrowck_const_not_used_in_type_alias = const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias - -borrowck_var_cannot_escape_closure = + +borrowck_var_cannot_escape_closure = captured variable cannot escape `FnMut` closure body .upvar_def = variable defined here .upvar = variable captured here @@ -35,23 +35,21 @@ borrowck_var_cannot_escape_closure = .note = `FnMut` closures only have access to their captured variables while they are executing... .cannot_escape = ...therefore, they cannot allow references to captured variables to escape -borrowck_returned_closure_escaped = +borrowck_returned_closure_escaped = returns a closure that contains a reference to a captured variable, which then escapes the closure body -borrowck_returned_async_block_escaped = +borrowck_returned_async_block_escaped = returns an `async` block that contains a reference to a captured variable, which then escapes the closure body -borrowck_returned_ref_escaped = +borrowck_returned_ref_escaped = returns a reference to a captured variable which escapes the closure body borrowck_lifetime_constraints_error = lifetime may not live long enough - + borrowck_returned_lifetime_wrong = {$mir_def_name} was supposed to return data with lifetime `{$outlived_fr_name}` but it is returning data with lifetime `{$fr_name}` borrowck_returned_lifetime_short = {$category_desc}requires that `{$free_region_name}` must outlive `{$outlived_fr_name}`" - -borrowck_impl_require_static = - the used `impl` has a `'static` requirement \ No newline at end of file + diff --git a/compiler/rustc_error_messages/locales/en-US/expand.ftl b/compiler/rustc_error_messages/locales/en-US/expand.ftl index ee76a4f45005d..5720591154f99 100644 --- a/compiler/rustc_error_messages/locales/en-US/expand.ftl +++ b/compiler/rustc_error_messages/locales/en-US/expand.ftl @@ -4,10 +4,10 @@ expand_explain_doc_comment_outer = expand_explain_doc_comment_inner = inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match -expand_expr_repeat_no_syntax_vars = +expand_expr_repeat_no_syntax_vars = attempted to repeat an expression containing no syntax variables matched as repeating at this depth -expand_must_repeat_once = +expand_must_repeat_once = this must repeat at least once expand_count_repetition_misplaced = @@ -19,4 +19,4 @@ expand_meta_var_expr_unrecognized_var = expand_var_still_repeating = variable '{$ident}' is still repeating at this depth -expand_meta_var_dif_seq_matchers = {$msg} \ No newline at end of file +expand_meta_var_dif_seq_matchers = {$msg} diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 04159bff4ff41..61d767a1cc6b4 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -84,6 +84,13 @@ pub trait EmissionGuarantee: Sized { /// of `Self` without actually performing the emission. #[track_caller] fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self; + + /// Creates a new `DiagnosticBuilder` that will return this type of guarantee. + #[track_caller] + fn make_diagnostic_builder( + handler: &Handler, + msg: impl Into, + ) -> DiagnosticBuilder<'_, Self>; } /// Private module for sealing the `IsError` helper trait. @@ -166,6 +173,15 @@ impl EmissionGuarantee for ErrorGuaranteed { } } } + + fn make_diagnostic_builder( + handler: &Handler, + msg: impl Into, + ) -> DiagnosticBuilder<'_, Self> { + DiagnosticBuilder::new_guaranteeing_error::<_, { Level::Error { lint: false } }>( + handler, msg, + ) + } } impl<'a> DiagnosticBuilder<'a, ()> { @@ -208,6 +224,13 @@ impl EmissionGuarantee for () { DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {} } } + + fn make_diagnostic_builder( + handler: &Handler, + msg: impl Into, + ) -> DiagnosticBuilder<'_, Self> { + DiagnosticBuilder::new(handler, Level::Warning(None), msg) + } } impl<'a> DiagnosticBuilder<'a, !> { @@ -247,6 +270,13 @@ impl EmissionGuarantee for ! { // Then fatally error, returning `!` crate::FatalError.raise() } + + fn make_diagnostic_builder( + handler: &Handler, + msg: impl Into, + ) -> DiagnosticBuilder<'_, Self> { + DiagnosticBuilder::new_fatal(handler, msg) + } } /// In general, the `DiagnosticBuilder` uses deref to allow access to diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 18e84b70b1b10..9b9c334d4dfcc 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -641,6 +641,15 @@ impl Handler { self.inner.borrow_mut().emit_stashed_diagnostics() } + /// Construct a builder with the `msg` at the level appropriate for the specific `EmissionGuarantee`. + #[rustc_lint_diagnostics] + pub fn struct_diagnostic( + &self, + msg: impl Into, + ) -> DiagnosticBuilder<'_, G> { + G::make_diagnostic_builder(self, msg) + } + /// Construct a builder at the `Warning` level at the given `span` and with the `msg`. /// /// Attempting to `.emit()` the builder will only emit if either: diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 852ea806b20ff..df56e032988c6 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -6,7 +6,7 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, Nonterminal}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{AssocCtxt, Visitor}; -use rustc_ast::{self as ast, Attribute, HasAttrs, Item, NodeId, PatKind}; +use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind}; use rustc_attr::{self as attr, Deprecation, Stability}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::sync::{self, Lrc}; @@ -71,7 +71,7 @@ impl Annotatable { } } - pub fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { + pub fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) { match self { Annotatable::Item(item) => item.visit_attrs(f), Annotatable::TraitItem(trait_item) => trait_item.visit_attrs(f), diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 0440bca53b232..c4890b4a9c413 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -575,7 +575,7 @@ impl<'a> ExtCtxt<'a> { &self, span: Span, name: Ident, - attrs: Vec, + attrs: ast::AttrVec, kind: ast::ItemKind, ) -> P { // FIXME: Would be nice if our generated code didn't violate @@ -603,7 +603,7 @@ impl<'a> ExtCtxt<'a> { mutbl: ast::Mutability, expr: P, ) -> P { - self.item(span, name, Vec::new(), ast::ItemKind::Static(ty, mutbl, Some(expr))) + self.item(span, name, AttrVec::new(), ast::ItemKind::Static(ty, mutbl, Some(expr))) } pub fn item_const( @@ -614,7 +614,7 @@ impl<'a> ExtCtxt<'a> { expr: P, ) -> P { let def = ast::Defaultness::Final; - self.item(span, name, Vec::new(), ast::ItemKind::Const(def, ty, Some(expr))) + self.item(span, name, AttrVec::new(), ast::ItemKind::Const(def, ty, Some(expr))) } pub fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute { diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 3e1acf4382d5b..48ee23d2c3d18 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -215,7 +215,7 @@ pub fn features( let features = match strip_unconfigured.configure_krate_attrs(krate.attrs) { None => { // The entire crate is unconfigured. - krate.attrs = Vec::new(); + krate.attrs = ast::AttrVec::new(); krate.items = Vec::new(); Features::default() } @@ -265,7 +265,7 @@ impl<'a> StripUnconfigured<'a> { } } - fn configure_krate_attrs(&self, mut attrs: Vec) -> Option> { + fn configure_krate_attrs(&self, mut attrs: ast::AttrVec) -> Option { attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr)); if self.in_cfg(&attrs) { Some(attrs) } else { None } } @@ -292,9 +292,7 @@ impl<'a> StripUnconfigured<'a> { .iter() .flat_map(|(tree, spacing)| match tree.clone() { AttrAnnotatedTokenTree::Attributes(mut data) => { - let mut attrs: Vec<_> = std::mem::take(&mut data.attrs).into(); - attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr)); - data.attrs = attrs.into(); + data.attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr)); if self.in_cfg(&data.attrs) { data.tokens = LazyTokenStream::new( diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index 0d7e137c7dd0c..0feae0debd227 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -3,28 +3,28 @@ use rustc_span::symbol::MacroRulesNormalizedIdent; use rustc_span::Span; #[derive(SessionDiagnostic)] -#[error(expand::expr_repeat_no_syntax_vars)] +#[diag(expand::expr_repeat_no_syntax_vars)] pub(crate) struct NoSyntaxVarsExprRepeat { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(expand::must_repeat_once)] +#[diag(expand::must_repeat_once)] pub(crate) struct MustRepeatOnce { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(expand::count_repetition_misplaced)] +#[diag(expand::count_repetition_misplaced)] pub(crate) struct CountRepetitionMisplaced { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(expand::meta_var_expr_unrecognized_var)] +#[diag(expand::meta_var_expr_unrecognized_var)] pub(crate) struct MetaVarExprUnrecognizedVar { #[primary_span] pub span: Span, @@ -32,7 +32,7 @@ pub(crate) struct MetaVarExprUnrecognizedVar { } #[derive(SessionDiagnostic)] -#[error(expand::var_still_repeating)] +#[diag(expand::var_still_repeating)] pub(crate) struct VarStillRepeating { #[primary_span] pub span: Span, @@ -40,7 +40,7 @@ pub(crate) struct VarStillRepeating { } #[derive(SessionDiagnostic)] -#[error(expand::meta_var_dif_seq_matchers)] +#[diag(expand::meta_var_dif_seq_matchers)] pub(crate) struct MetaVarsDifSeqMatchers { #[primary_span] pub span: Span, diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index cc72dab84afa2..c2add852a0679 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -11,7 +11,7 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{self, AssocCtxt, Visitor}; -use rustc_ast::{AssocItemKind, AstNodeWrapper, AttrStyle, ExprKind, ForeignItemKind}; +use rustc_ast::{AssocItemKind, AstNodeWrapper, AttrStyle, AttrVec, ExprKind, ForeignItemKind}; use rustc_ast::{HasAttrs, HasNodeId}; use rustc_ast::{Inline, ItemKind, MacArgs, MacStmtStyle, MetaItemKind, ModKind}; use rustc_ast::{NestedMetaItem, NodeId, PatKind, StmtKind, TyKind}; @@ -1001,7 +1001,7 @@ enum AddSemicolon { /// of functionality used by `InvocationCollector`. trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized { type OutputTy = SmallVec<[Self; 1]>; - type AttrsTy: Deref = Vec; + type AttrsTy: Deref = ast::AttrVec; const KIND: AstFragmentKind; fn to_annotatable(self) -> Annotatable; fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy; @@ -1333,7 +1333,7 @@ impl InvocationCollectorNode for ast::Stmt { } StmtKind::Item(item) => match item.into_inner() { ast::Item { kind: ItemKind::MacCall(mac), attrs, .. } => { - (mac.args.need_semicolon(), mac, attrs.into()) + (mac.args.need_semicolon(), mac, attrs) } _ => unreachable!(), }, @@ -1390,7 +1390,7 @@ impl InvocationCollectorNode for P { fn take_mac_call(self) -> (P, Self::AttrsTy, AddSemicolon) { let node = self.into_inner(); match node.kind { - TyKind::MacCall(mac) => (mac, Vec::new(), AddSemicolon::No), + TyKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No), _ => unreachable!(), } } @@ -1414,7 +1414,7 @@ impl InvocationCollectorNode for P { fn take_mac_call(self) -> (P, Self::AttrsTy, AddSemicolon) { let node = self.into_inner(); match node.kind { - PatKind::MacCall(mac) => (mac, Vec::new(), AddSemicolon::No), + PatKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No), _ => unreachable!(), } } @@ -1646,7 +1646,11 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { fn expand_cfg_attr(&self, node: &mut impl HasAttrs, attr: ast::Attribute, pos: usize) { node.visit_attrs(|attrs| { - attrs.splice(pos..pos, self.cfg().expand_cfg_attr(attr, false)); + // Repeated `insert` calls is inefficient, but the number of + // insertions is almost always 0 or 1 in practice. + for cfg in self.cfg().expand_cfg_attr(attr, false).into_iter().rev() { + attrs.insert(pos, cfg) + } }); } diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs index 0315d11634c6b..9002a24e42f9d 100644 --- a/compiler/rustc_expand/src/module.rs +++ b/compiler/rustc_expand/src/module.rs @@ -1,6 +1,6 @@ use crate::base::ModuleData; use rustc_ast::ptr::P; -use rustc_ast::{token, Attribute, Inline, Item, ModSpans}; +use rustc_ast::{token, AttrVec, Attribute, Inline, Item, ModSpans}; use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorGuaranteed}; use rustc_parse::new_parser_from_file; use rustc_parse::validate_attr; @@ -48,7 +48,7 @@ pub(crate) fn parse_external_mod( span: Span, // The span to blame on errors. module: &ModuleData, mut dir_ownership: DirOwnership, - attrs: &mut Vec, + attrs: &mut AttrVec, ) -> ParsedExternalMod { // We bail on the first error, but that error does not cause a fatal error... (1) let result: Result<_, ModError<'_>> = try { @@ -63,9 +63,9 @@ pub(crate) fn parse_external_mod( // Actually parse the external file as a module. let mut parser = new_parser_from_file(&sess.parse_sess, &mp.file_path, Some(span)); - let (mut inner_attrs, items, inner_span) = + let (inner_attrs, items, inner_span) = parser.parse_mod(&token::Eof).map_err(|err| ModError::ParserError(err))?; - attrs.append(&mut inner_attrs); + attrs.extend(inner_attrs); (items, inner_span, mp.file_path) }; // (1) ...instead, we return a dummy module. diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 48918541e72fc..3b0d5ddb97b4e 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -24,7 +24,7 @@ pub fn placeholder( } let ident = Ident::empty(); - let attrs = Vec::new(); + let attrs = ast::AttrVec::new(); let vis = vis.unwrap_or(ast::Visibility { span: DUMMY_SP, kind: ast::VisibilityKind::Inherited, diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 8fb5f159136be..59ea1f3f9de45 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -740,12 +740,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.help("...or use `match` instead of `let...else`"); } _ => { - if let ObligationCauseCode::BindingObligation(_, binding_span) = - cause.code().peel_derives() + if let ObligationCauseCode::BindingObligation(_, span) + | ObligationCauseCode::ExprBindingObligation(_, span, ..) + = cause.code().peel_derives() + && let TypeError::RegionsPlaceholderMismatch = terr { - if matches!(terr, TypeError::RegionsPlaceholderMismatch) { - err.span_note(*binding_span, "the lifetime requirement is introduced here"); - } + err.span_note(*span, "the lifetime requirement is introduced here"); } } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index 893ca3cf79d70..c20b96cae2e4f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -35,7 +35,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let ObligationCauseCode::MatchImpl(parent, impl_def_id) = code else { return None; }; - let ObligationCauseCode::BindingObligation(_def_id, binding_span) = *parent.code() else { + let (ObligationCauseCode::BindingObligation(_, binding_span) | ObligationCauseCode::ExprBindingObligation(_, binding_span, ..)) + = *parent.code() else { return None; }; let mut err = self.tcx().sess.struct_span_err(cause.span, "incompatible lifetime on type"); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index 998699158ff48..d4db0751212f7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -211,7 +211,10 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { ); let mut err = self.tcx().sess.struct_span_err(span, &msg); - let leading_ellipsis = if let ObligationCauseCode::ItemObligation(def_id) = *cause.code() { + let leading_ellipsis = if let ObligationCauseCode::ItemObligation(def_id) + | ObligationCauseCode::ExprItemObligation(def_id, ..) = + *cause.code() + { err.span_label(span, "doesn't satisfy where-clause"); err.span_label( self.tcx().def_span(def_id), diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 9886c572a8aaf..f804569b0747e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -232,7 +232,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ObligationCauseCode::MatchImpl(parent, ..) => parent.code(), _ => cause.code(), } - && let (&ObligationCauseCode::ItemObligation(item_def_id), None) = (code, override_error_code) + && let (&ObligationCauseCode::ItemObligation(item_def_id) | &ObligationCauseCode::ExprItemObligation(item_def_id, ..), None) = (code, override_error_code) { // Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static` // lifetime as above, but called using a fully-qualified path to the method: diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 8dabdfd55c7e8..8c465b0876002 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -390,10 +390,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if matches!( &trace.cause.code().peel_derives(), ObligationCauseCode::BindingObligation(..) + | ObligationCauseCode::ExprBindingObligation(..) ) => { // Hack to get around the borrow checker because trace.cause has an `Rc`. - if let ObligationCauseCode::BindingObligation(_, span) = + if let ObligationCauseCode::BindingObligation(_, span) + | ObligationCauseCode::ExprBindingObligation(_, span, ..) = &trace.cause.code().peel_derives() { let span = *span; diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index ad052f58ca854..dded0a0a6b1b4 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -97,7 +97,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { cause.span, sup_type, match cause.code().peel_derives() { - ObligationCauseCode::BindingObligation(_, span) => Some(*span), + ObligationCauseCode::BindingObligation(_, span) + | ObligationCauseCode::ExprBindingObligation(_, span, ..) => Some(*span), _ => None, }, ) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index e00d0b7d0d82f..014cf88389e44 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -265,7 +265,7 @@ impl LintStoreExpand for LintStoreExpandImpl<'_> { } #[derive(SessionDiagnostic)] -#[error(interface::ferris_identifier)] +#[diag(interface::ferris_identifier)] struct FerrisIdentifier { #[primary_span] spans: Vec, @@ -274,7 +274,7 @@ struct FerrisIdentifier { } #[derive(SessionDiagnostic)] -#[error(interface::emoji_identifier)] +#[diag(interface::emoji_identifier)] struct EmojiIdentifier { #[primary_span] spans: Vec, diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index cafd2c6e67994..484e541afc587 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1546,7 +1546,7 @@ impl InvalidAtomicOrdering { if matches!(fail_ordering, sym::Release | sym::AcqRel) { #[derive(LintDiagnostic)] - #[lint(lint::atomic_ordering_invalid)] + #[diag(lint::atomic_ordering_invalid)] #[help] struct InvalidAtomicOrderingDiag { method: Symbol, diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index b4314223722fc..05d2a214d0b79 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -31,6 +31,9 @@ #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/IPO/AlwaysInliner.h" #include "llvm/Transforms/IPO/FunctionImport.h" +#if LLVM_VERSION_GE(15, 0) +#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" +#endif #include "llvm/Transforms/Utils/AddDiscriminators.h" #include "llvm/Transforms/Utils/FunctionImportUtils.h" #include "llvm/LTO/LTO.h" @@ -1587,13 +1590,31 @@ LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) { { raw_string_ostream OS(Ret->data); { - legacy::PassManager PM; if (is_thin) { +#if LLVM_VERSION_LT(15, 0) + legacy::PassManager PM; PM.add(createWriteThinLTOBitcodePass(OS)); + PM.run(*unwrap(M)); +#else + PassBuilder PB; + LoopAnalysisManager LAM; + FunctionAnalysisManager FAM; + CGSCCAnalysisManager CGAM; + ModuleAnalysisManager MAM; + PB.registerModuleAnalyses(MAM); + PB.registerCGSCCAnalyses(CGAM); + PB.registerFunctionAnalyses(FAM); + PB.registerLoopAnalyses(LAM); + PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); + ModulePassManager MPM; + MPM.addPass(ThinLTOBitcodeWriterPass(OS, nullptr)); + MPM.run(*unwrap(M), MAM); +#endif } else { + legacy::PassManager PM; PM.add(createBitcodeWriterPass(OS)); + PM.run(*unwrap(M)); } - PM.run(*unwrap(M)); } } return Ret.release(); diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 6b5b8b5932018..244edec284159 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -21,7 +21,7 @@ impl<'a> SessionDiagnosticDerive<'a> { builder: DiagnosticDeriveBuilder { diag, fields: build_field_mapping(&structure), - kind: None, + kind: DiagnosticDeriveKind::SessionDiagnostic, code: None, slug: None, }, @@ -34,49 +34,31 @@ impl<'a> SessionDiagnosticDerive<'a> { let SessionDiagnosticDerive { mut structure, sess, mut builder } = self; let ast = structure.ast(); - let (implementation, param_ty) = { + let implementation = { if let syn::Data::Struct(..) = ast.data { let preamble = builder.preamble(&structure); let (attrs, args) = builder.body(&mut structure); let span = ast.span().unwrap(); let diag = &builder.diag; - let init = match (builder.kind.value(), builder.slug.value()) { - (None, _) => { - span_err(span, "diagnostic kind not specified") - .help("use the `#[error(...)]` attribute to create an error") - .emit(); - return DiagnosticDeriveError::ErrorHandled.to_compile_error(); - } - (Some(kind), None) => { + let init = match builder.slug.value() { + None => { span_err(span, "diagnostic slug not specified") .help(&format!( - "specify the slug as the first argument to the attribute, such as \ - `#[{}(typeck::example_error)]`", - kind.descr() + "specify the slug as the first argument to the `#[diag(...)]` attribute, \ + such as `#[diag(typeck::example_error)]`", )) .emit(); return DiagnosticDeriveError::ErrorHandled.to_compile_error(); } - (Some(DiagnosticDeriveKind::Lint), _) => { - span_err(span, "only `#[error(..)]` and `#[warning(..)]` are supported") - .help("use the `#[error(...)]` attribute to create a error") - .emit(); - return DiagnosticDeriveError::ErrorHandled.to_compile_error(); - } - (Some(DiagnosticDeriveKind::Error), Some(slug)) => { - quote! { - let mut #diag = #sess.struct_err(rustc_errors::fluent::#slug); - } - } - (Some(DiagnosticDeriveKind::Warn), Some(slug)) => { + Some(slug) => { quote! { - let mut #diag = #sess.struct_warn(rustc_errors::fluent::#slug); + let mut #diag = #sess.struct_diagnostic(rustc_errors::fluent::#slug); } } }; - let implementation = quote! { + quote! { #init #preamble match self { @@ -86,18 +68,7 @@ impl<'a> SessionDiagnosticDerive<'a> { #args } #diag - }; - let param_ty = match builder.kind { - Some((DiagnosticDeriveKind::Error, _)) => { - quote! { rustc_errors::ErrorGuaranteed } - } - Some((DiagnosticDeriveKind::Lint | DiagnosticDeriveKind::Warn, _)) => { - quote! { () } - } - _ => unreachable!(), - }; - - (implementation, param_ty) + } } else { span_err( ast.span().unwrap(), @@ -105,20 +76,20 @@ impl<'a> SessionDiagnosticDerive<'a> { ) .emit(); - let implementation = DiagnosticDeriveError::ErrorHandled.to_compile_error(); - let param_ty = quote! { rustc_errors::ErrorGuaranteed }; - (implementation, param_ty) + DiagnosticDeriveError::ErrorHandled.to_compile_error() } }; structure.gen_impl(quote! { - gen impl<'__session_diagnostic_sess> rustc_session::SessionDiagnostic<'__session_diagnostic_sess, #param_ty> + gen impl<'__session_diagnostic_sess, G> + rustc_session::SessionDiagnostic<'__session_diagnostic_sess, G> for @Self + where G: rustc_errors::EmissionGuarantee { fn into_diagnostic( self, #sess: &'__session_diagnostic_sess rustc_session::parse::ParseSess - ) -> rustc_errors::DiagnosticBuilder<'__session_diagnostic_sess, #param_ty> { + ) -> rustc_errors::DiagnosticBuilder<'__session_diagnostic_sess, G> { use rustc_errors::IntoDiagnosticArg; #implementation } @@ -139,7 +110,7 @@ impl<'a> LintDiagnosticDerive<'a> { builder: DiagnosticDeriveBuilder { diag, fields: build_field_mapping(&structure), - kind: None, + kind: DiagnosticDeriveKind::LintDiagnostic, code: None, slug: None, }, @@ -158,30 +129,17 @@ impl<'a> LintDiagnosticDerive<'a> { let diag = &builder.diag; let span = ast.span().unwrap(); - let init = match (builder.kind.value(), builder.slug.value()) { - (None, _) => { - span_err(span, "diagnostic kind not specified") - .help("use the `#[error(...)]` attribute to create an error") - .emit(); - return DiagnosticDeriveError::ErrorHandled.to_compile_error(); - } - (Some(kind), None) => { + let init = match builder.slug.value() { + None => { span_err(span, "diagnostic slug not specified") .help(&format!( "specify the slug as the first argument to the attribute, such as \ - `#[{}(typeck::example_error)]`", - kind.descr() + `#[diag(typeck::example_error)]`", )) .emit(); return DiagnosticDeriveError::ErrorHandled.to_compile_error(); } - (Some(DiagnosticDeriveKind::Error | DiagnosticDeriveKind::Warn), _) => { - span_err(span, "only `#[lint(..)]` is supported") - .help("use the `#[lint(...)]` attribute to create a lint") - .emit(); - return DiagnosticDeriveError::ErrorHandled.to_compile_error(); - } - (Some(DiagnosticDeriveKind::Lint), Some(slug)) => { + Some(slug) => { quote! { let mut #diag = #diag.build(rustc_errors::fluent::#slug); } diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index 6c9561925fe8c..9df9fa4e9bf74 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -18,30 +18,15 @@ use syn::{ }; use synstructure::{BindingInfo, Structure}; -/// What kind of diagnostic is being derived - an error, a warning or a lint? -#[derive(Copy, Clone)] +/// What kind of diagnostic is being derived - a fatal/error/warning or a lint? +#[derive(Copy, Clone, PartialEq, Eq)] pub(crate) enum DiagnosticDeriveKind { - /// `#[error(..)]` - Error, - /// `#[warn(..)]` - Warn, - /// `#[lint(..)]` - Lint, -} - -impl DiagnosticDeriveKind { - /// Returns human-readable string corresponding to the kind. - pub fn descr(&self) -> &'static str { - match self { - DiagnosticDeriveKind::Error => "error", - DiagnosticDeriveKind::Warn => "warning", - DiagnosticDeriveKind::Lint => "lint", - } - } + SessionDiagnostic, + LintDiagnostic, } /// Tracks persistent information required for building up individual calls to diagnostic methods -/// for generated diagnostic derives - both `SessionDiagnostic` for errors/warnings and +/// for generated diagnostic derives - both `SessionDiagnostic` for fatal/errors/warnings and /// `LintDiagnostic` for lints. pub(crate) struct DiagnosticDeriveBuilder { /// The identifier to use for the generated `DiagnosticBuilder` instance. @@ -51,8 +36,8 @@ pub(crate) struct DiagnosticDeriveBuilder { /// derive builder. pub fields: HashMap, - /// Kind of diagnostic requested via the struct attribute. - pub kind: Option<(DiagnosticDeriveKind, proc_macro::Span)>, + /// Kind of diagnostic that should be derived. + pub kind: DiagnosticDeriveKind, /// Slug is a mandatory part of the struct attribute as corresponds to the Fluent message that /// has the actual diagnostic message. pub slug: Option<(Path, proc_macro::Span)>, @@ -143,7 +128,7 @@ impl DiagnosticDeriveBuilder { } /// Establishes state in the `DiagnosticDeriveBuilder` resulting from the struct - /// attributes like `#[error(..)`, such as the diagnostic kind and slug. Generates + /// attributes like `#[diag(..)]`, such as the slug and error code. Generates /// diagnostic builder calls for setting error code and creating note/help messages. fn generate_structure_code_for_attr( &mut self, @@ -156,15 +141,15 @@ impl DiagnosticDeriveBuilder { let name = name.as_str(); let meta = attr.parse_meta()?; - let is_help_note_or_warn = matches!(name, "help" | "note" | "warn_"); + let is_diag = name == "diag"; let nested = match meta { - // Most attributes are lists, like `#[error(..)]`/`#[warning(..)]` for most cases or + // Most attributes are lists, like `#[diag(..)]` for most cases or // `#[help(..)]`/`#[note(..)]` when the user is specifying a alternative slug. Meta::List(MetaList { ref nested, .. }) => nested, // Subdiagnostics without spans can be applied to the type too, and these are just - // paths: `#[help]` and `#[note]` - Meta::Path(_) if is_help_note_or_warn => { + // paths: `#[help]`, `#[note]` and `#[warn_]` + Meta::Path(_) if !is_diag => { let fn_name = if name == "warn_" { Ident::new("warn", attr.span()) } else { @@ -178,23 +163,21 @@ impl DiagnosticDeriveBuilder { // Check the kind before doing any further processing so that there aren't misleading // "no kind specified" errors if there are failures later. match name { - "error" => self.kind.set_once((DiagnosticDeriveKind::Error, span)), - "warning" => self.kind.set_once((DiagnosticDeriveKind::Warn, span)), - "lint" => self.kind.set_once((DiagnosticDeriveKind::Lint, span)), - "help" | "note" | "warn_" => (), + "error" | "warning" | "lint" => throw_invalid_attr!(attr, &meta, |diag| { + diag.help("`error`, `warning` and `lint` have been replaced by `diag`") + }), + "diag" | "help" | "note" | "warn_" => (), _ => throw_invalid_attr!(attr, &meta, |diag| { - diag.help( - "only `error`, `warning`, `help`, `note` and `warn_` are valid attributes", - ) + diag.help("only `diag`, `help`, `note` and `warn_` are valid attributes") }), } - // First nested element should always be the path, e.g. `#[error(typeck::invalid)]` or + // First nested element should always be the path, e.g. `#[diag(typeck::invalid)]` or // `#[help(typeck::another_help)]`. let mut nested_iter = nested.into_iter(); if let Some(nested_attr) = nested_iter.next() { // Report an error if there are any other list items after the path. - if is_help_note_or_warn && nested_iter.next().is_some() { + if !is_diag && nested_iter.next().is_some() { throw_invalid_nested_attr!(attr, &nested_attr, |diag| { diag.help( "`help`, `note` and `warn_` struct attributes can only have one argument", @@ -203,16 +186,16 @@ impl DiagnosticDeriveBuilder { } match nested_attr { - NestedMeta::Meta(Meta::Path(path)) if is_help_note_or_warn => { - let fn_name = proc_macro2::Ident::new(name, attr.span()); - return Ok(quote! { #diag.#fn_name(rustc_errors::fluent::#path); }); - } NestedMeta::Meta(Meta::Path(path)) => { - self.slug.set_once((path.clone(), span)); + if is_diag { + self.slug.set_once((path.clone(), span)); + } else { + let fn_name = proc_macro2::Ident::new(name, attr.span()); + return Ok(quote! { #diag.#fn_name(rustc_errors::fluent::#path); }); + } } NestedMeta::Meta(meta @ Meta::NameValue(_)) - if !is_help_note_or_warn - && meta.path().segments.last().unwrap().ident == "code" => + if is_diag && meta.path().segments.last().unwrap().ident == "code" => { // don't error for valid follow-up attributes } @@ -346,10 +329,20 @@ impl DiagnosticDeriveBuilder { Ok(quote! {}) } "primary_span" => { - report_error_if_not_applied_to_span(attr, &info)?; - Ok(quote! { - #diag.set_span(#binding); - }) + match self.kind { + DiagnosticDeriveKind::SessionDiagnostic => { + report_error_if_not_applied_to_span(attr, &info)?; + + Ok(quote! { + #diag.set_span(#binding); + }) + } + DiagnosticDeriveKind::LintDiagnostic => { + throw_invalid_attr!(attr, &meta, |diag| { + diag.help("the `primary_span` field attribute is not valid for lint diagnostics") + }) + } + } } "label" => { report_error_if_not_applied_to_span(attr, &info)?; diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs index 733454cb2a747..2ff21e18ff853 100644 --- a/compiler/rustc_macros/src/diagnostics/mod.rs +++ b/compiler/rustc_macros/src/diagnostics/mod.rs @@ -23,7 +23,7 @@ use synstructure::Structure; /// # extern crate rust_middle; /// # use rustc_middle::ty::Ty; /// #[derive(SessionDiagnostic)] -/// #[error(borrowck::move_out_of_borrow, code = "E0505")] +/// #[diag(borrowck::move_out_of_borrow, code = "E0505")] /// pub struct MoveOutOfBorrowError<'tcx> { /// pub name: Ident, /// pub ty: Ty<'tcx>, @@ -67,7 +67,7 @@ pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream { /// /// ```ignore (rust) /// #[derive(LintDiagnostic)] -/// #[lint(lint::atomic_ordering_invalid_fail_success)] +/// #[diag(lint::atomic_ordering_invalid_fail_success)] /// pub struct AtomicOrderingInvalidLint { /// method: Symbol, /// success_ordering: Symbol, diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index e01d035767ba6..87d7ab6ed517b 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -129,9 +129,7 @@ decl_derive!([Lift, attributes(lift)] => lift::lift_derive); decl_derive!( [SessionDiagnostic, attributes( // struct attributes - warning, - error, - lint, + diag, help, note, warn_, @@ -148,9 +146,7 @@ decl_derive!( decl_derive!( [LintDiagnostic, attributes( // struct attributes - warning, - error, - lint, + diag, help, note, warn_, diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 72b848c3ee2dd..9b82320e556b3 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -234,13 +234,23 @@ pub enum ObligationCauseCode<'tcx> { /// This is the trait reference from the given projection. ProjectionWf(ty::ProjectionTy<'tcx>), - /// In an impl of trait `X` for type `Y`, type `Y` must - /// also implement all supertraits of `X`. + /// Must satisfy all of the where-clause predicates of the + /// given item. ItemObligation(DefId), - /// Like `ItemObligation`, but with extra detail on the source of the obligation. + /// Like `ItemObligation`, but carries the span of the + /// predicate when it can be identified. BindingObligation(DefId, Span), + /// Like `ItemObligation`, but carries the `HirId` of the + /// expression that caused the obligation, and the `usize` + /// indicates exactly which predicate it is in the list of + /// instantiated predicates. + ExprItemObligation(DefId, rustc_hir::HirId, usize), + + /// Combines `ExprItemObligation` and `BindingObligation`. + ExprBindingObligation(DefId, Span, rustc_hir::HirId, usize), + /// A type like `&'a T` is WF only if `T: 'a`. ReferenceOutlivesReferent(Ty<'tcx>), diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index add2df25884e3..823e7f22af24d 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -122,6 +122,21 @@ pub struct Generics { } impl<'tcx> Generics { + /// Looks through the generics and all parents to find the index of the + /// given param def-id. This is in comparison to the `param_def_id_to_index` + /// struct member, which only stores information about this item's own + /// generics. + pub fn param_def_id_to_index(&self, tcx: TyCtxt<'tcx>, def_id: DefId) -> Option { + if let Some(idx) = self.param_def_id_to_index.get(&def_id) { + Some(*idx) + } else if let Some(parent) = self.parent { + let parent = tcx.generics_of(parent); + parent.param_def_id_to_index(tcx, def_id) + } else { + None + } + } + #[inline] pub fn count(&self) -> usize { self.parent_count + self.params.len() diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 96bbf5802e738..82ef16a7f72fc 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -128,7 +128,7 @@ //! #### Unsizing Casts //! A subtle way of introducing neighbor edges is by casting to a trait object. //! Since the resulting fat-pointer contains a reference to a vtable, we need to -//! instantiate all object-save methods of the trait, as we need to store +//! instantiate all object-safe methods of the trait, as we need to store //! pointers to these functions even if they never get called anywhere. This can //! be seen as a special case of taking a function reference. //! @@ -1044,10 +1044,12 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> /// them. /// /// For example, the source type might be `&SomeStruct` and the target type -/// might be `&SomeTrait` in a cast like: +/// might be `&dyn SomeTrait` in a cast like: /// +/// ```rust,ignore (not real code) /// let src: &SomeStruct = ...; -/// let target = src as &SomeTrait; +/// let target = src as &dyn SomeTrait; +/// ``` /// /// Then the output of this function would be (SomeStruct, SomeTrait) since for /// constructing the `target` fat-pointer we need the vtable for that pair. @@ -1068,8 +1070,10 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> /// for the pair of `T` (which is a trait) and the concrete type that `T` was /// originally coerced from: /// +/// ```rust,ignore (not real code) /// let src: &ComplexStruct = ...; -/// let target = src as &ComplexStruct; +/// let target = src as &ComplexStruct; +/// ``` /// /// Again, we want this `find_vtable_types_for_unsizing()` to provide the pair /// `(SomeStruct, SomeTrait)`. diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 5924eba9f8b42..3691d82a835a9 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -62,7 +62,7 @@ pub fn parse_crate_from_file<'a>(input: &Path, sess: &'a ParseSess) -> PResult<' pub fn parse_crate_attrs_from_file<'a>( input: &Path, sess: &'a ParseSess, -) -> PResult<'a, Vec> { +) -> PResult<'a, ast::AttrVec> { let mut parser = new_parser_from_file(sess, input, None); parser.parse_inner_attributes() } @@ -79,7 +79,7 @@ pub fn parse_crate_attrs_from_source_str( name: FileName, source: String, sess: &ParseSess, -) -> PResult<'_, Vec> { +) -> PResult<'_, ast::AttrVec> { new_parser_from_source_str(sess, name, source).parse_inner_attributes() } diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index acdbddf4099e6..72ab96b5ca670 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -34,7 +34,7 @@ enum OuterAttributeType { impl<'a> Parser<'a> { /// Parses attributes that appear before an item. pub(super) fn parse_outer_attributes(&mut self) -> PResult<'a, AttrWrapper> { - let mut outer_attrs: Vec = Vec::new(); + let mut outer_attrs = ast::AttrVec::new(); let mut just_parsed_doc_comment = false; let start_pos = self.token_cursor.num_next_calls; loop { @@ -106,7 +106,7 @@ impl<'a> Parser<'a> { break; } } - Ok(AttrWrapper::new(outer_attrs.into(), start_pos)) + Ok(AttrWrapper::new(outer_attrs, start_pos)) } /// Matches `attribute = # ! [ meta_item ]`. @@ -283,8 +283,8 @@ impl<'a> Parser<'a> { /// terminated by a semicolon. /// /// Matches `inner_attrs*`. - pub(crate) fn parse_inner_attributes(&mut self) -> PResult<'a, Vec> { - let mut attrs: Vec = vec![]; + pub(crate) fn parse_inner_attributes(&mut self) -> PResult<'a, ast::AttrVec> { + let mut attrs = ast::AttrVec::new(); loop { let start_pos: u32 = self.token_cursor.num_next_calls.try_into().unwrap(); // Only try to parse if it is an inner attribute (has `!`). diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 6c750ff428f53..ed54af9f53fb7 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -15,11 +15,11 @@ use std::ops::Range; /// for the attribute target. This allows us to perform cfg-expansion on /// a token stream before we invoke a derive proc-macro. /// -/// This wrapper prevents direct access to the underlying `Vec`. +/// This wrapper prevents direct access to the underlying `ast::AttrVec>`. /// Parsing code can only get access to the underlying attributes /// by passing an `AttrWrapper` to `collect_tokens_trailing_tokens`. /// This makes it difficult to accidentally construct an AST node -/// (which stores a `Vec`) without first collecting tokens. +/// (which stores an `ast::AttrVec`) without first collecting tokens. /// /// This struct has its own module, to ensure that the parser code /// cannot directly access the `attrs` field @@ -49,9 +49,10 @@ impl AttrWrapper { self.attrs } + // Prepend `self.attrs` to `attrs`. // FIXME: require passing an NT to prevent misuse of this method - pub(crate) fn prepend_to_nt_inner(self, attrs: &mut Vec) { - let mut self_attrs: Vec<_> = self.attrs.into(); + pub(crate) fn prepend_to_nt_inner(self, attrs: &mut AttrVec) { + let mut self_attrs = self.attrs.clone(); std::mem::swap(attrs, &mut self_attrs); attrs.extend(self_attrs); } @@ -196,7 +197,7 @@ impl<'a> Parser<'a> { &mut self, attrs: AttrWrapper, force_collect: ForceCollect, - f: impl FnOnce(&mut Self, Vec) -> PResult<'a, (R, TrailingToken)>, + f: impl FnOnce(&mut Self, ast::AttrVec) -> PResult<'a, (R, TrailingToken)>, ) -> PResult<'a, R> { // We only bail out when nothing could possibly observe the collected tokens: // 1. We cannot be force collecting tokens (since force-collecting requires tokens @@ -212,7 +213,7 @@ impl<'a> Parser<'a> { // or `#[cfg_attr]` attributes. && !self.capture_cfg { - return Ok(f(self, attrs.attrs.into())?.0); + return Ok(f(self, attrs.attrs)?.0); } let start_token = (self.token.clone(), self.token_spacing); @@ -222,7 +223,7 @@ impl<'a> Parser<'a> { let prev_capturing = std::mem::replace(&mut self.capture_state.capturing, Capturing::Yes); let replace_ranges_start = self.capture_state.replace_ranges.len(); - let ret = f(self, attrs.attrs.into()); + let ret = f(self, attrs.attrs); self.capture_state.capturing = prev_capturing; @@ -352,7 +353,7 @@ impl<'a> Parser<'a> { // on the captured token stream. if self.capture_cfg && matches!(self.capture_state.capturing, Capturing::Yes) - && has_cfg_or_cfg_attr(&final_attrs) + && has_cfg_or_cfg_attr(final_attrs) { let attr_data = AttributesData { attrs: final_attrs.to_vec().into(), tokens }; diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 744ec7e611402..d7facb29714bc 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -244,7 +244,7 @@ impl MultiSugg { } #[derive(SessionDiagnostic)] -#[error(parser::maybe_report_ambiguous_plus)] +#[diag(parser::maybe_report_ambiguous_plus)] struct AmbiguousPlus { pub sum_ty: String, #[primary_span] @@ -253,7 +253,7 @@ struct AmbiguousPlus { } #[derive(SessionDiagnostic)] -#[error(parser::maybe_recover_from_bad_type_plus, code = "E0178")] +#[diag(parser::maybe_recover_from_bad_type_plus, code = "E0178")] struct BadTypePlus { pub ty: String, #[primary_span] @@ -287,7 +287,7 @@ pub enum BadTypePlusSub { } #[derive(SessionDiagnostic)] -#[error(parser::maybe_recover_from_bad_qpath_stage_2)] +#[diag(parser::maybe_recover_from_bad_qpath_stage_2)] struct BadQPathStage2 { #[primary_span] #[suggestion(applicability = "maybe-incorrect")] @@ -296,7 +296,7 @@ struct BadQPathStage2 { } #[derive(SessionDiagnostic)] -#[error(parser::incorrect_semicolon)] +#[diag(parser::incorrect_semicolon)] struct IncorrectSemicolon<'a> { #[primary_span] #[suggestion_short(applicability = "machine-applicable")] @@ -307,7 +307,7 @@ struct IncorrectSemicolon<'a> { } #[derive(SessionDiagnostic)] -#[error(parser::incorrect_use_of_await)] +#[diag(parser::incorrect_use_of_await)] struct IncorrectUseOfAwait { #[primary_span] #[suggestion(parser::parentheses_suggestion, applicability = "machine-applicable")] @@ -315,7 +315,7 @@ struct IncorrectUseOfAwait { } #[derive(SessionDiagnostic)] -#[error(parser::incorrect_use_of_await)] +#[diag(parser::incorrect_use_of_await)] struct IncorrectAwait { #[primary_span] span: Span, @@ -326,7 +326,7 @@ struct IncorrectAwait { } #[derive(SessionDiagnostic)] -#[error(parser::in_in_typo)] +#[diag(parser::in_in_typo)] struct InInTypo { #[primary_span] span: Span, @@ -335,7 +335,7 @@ struct InInTypo { } #[derive(SessionDiagnostic)] -#[error(parser::invalid_variable_declaration)] +#[diag(parser::invalid_variable_declaration)] pub struct InvalidVariableDeclaration { #[primary_span] pub span: Span, @@ -2370,7 +2370,7 @@ impl<'a> Parser<'a> { fn recover_const_param_decl(&mut self, ty_generics: Option<&Generics>) -> Option { let snapshot = self.create_snapshot_for_diagnostic(); - let param = match self.parse_const_param(vec![]) { + let param = match self.parse_const_param(AttrVec::new()) { Ok(param) => param, Err(err) => { err.cancel(); diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index df092f55bfae9..9fb9199231fb0 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -950,15 +950,15 @@ impl<'a> Parser<'a> { &mut self, e0: P, lo: Span, - mut attrs: Vec, + mut attrs: ast::AttrVec, ) -> PResult<'a, P> { // Stitch the list of outer attributes onto the return value. // A little bit ugly, but the best way given the current code // structure self.parse_dot_or_call_expr_with_(e0, lo).map(|expr| { expr.map(|mut expr| { - attrs.extend::>(expr.attrs.into()); - expr.attrs = attrs.into(); + attrs.extend(expr.attrs); + expr.attrs = attrs; expr }) }) @@ -2224,7 +2224,7 @@ impl<'a> Parser<'a> { Ok(( Param { - attrs: attrs.into(), + attrs, ty, pat, span: lo.to(this.prev_token.span), @@ -2732,7 +2732,7 @@ impl<'a> Parser<'a> { let span = body.span; return Ok(( ast::Arm { - attrs: attrs.into(), + attrs, pat, guard, body, @@ -2810,7 +2810,7 @@ impl<'a> Parser<'a> { Ok(( ast::Arm { - attrs: attrs.into(), + attrs, pat, guard, body: expr, @@ -3123,7 +3123,7 @@ impl<'a> Parser<'a> { span: lo.to(expr.span), expr, is_shorthand, - attrs: attrs.into(), + attrs, id: DUMMY_NODE_ID, is_placeholder: false, }, @@ -3219,14 +3219,10 @@ impl<'a> Parser<'a> { await_expr } - pub(crate) fn mk_expr_with_attrs(&self, span: Span, kind: ExprKind, attrs: A) -> P - where - A: Into, - { - P(Expr { kind, span, attrs: attrs.into(), id: DUMMY_NODE_ID, tokens: None }) + pub(crate) fn mk_expr_with_attrs(&self, span: Span, kind: ExprKind, attrs: AttrVec) -> P { + P(Expr { kind, span, attrs, id: DUMMY_NODE_ID, tokens: None }) } - // njn: rename pub(crate) fn mk_expr(&self, span: Span, kind: ExprKind) -> P { P(Expr { kind, span, attrs: AttrVec::new(), id: DUMMY_NODE_ID, tokens: None }) } @@ -3248,7 +3244,7 @@ impl<'a> Parser<'a> { fn collect_tokens_for_expr( &mut self, attrs: AttrWrapper, - f: impl FnOnce(&mut Self, Vec) -> PResult<'a, P>, + f: impl FnOnce(&mut Self, ast::AttrVec) -> PResult<'a, P>, ) -> PResult<'a, P> { self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { let res = f(this, attrs)?; diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 5e5f2fd7d9f8d..4d0a8b05eb027 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -1,9 +1,7 @@ use super::{ForceCollect, Parser, TrailingToken}; use rustc_ast::token; -use rustc_ast::{ - self as ast, Attribute, GenericBounds, GenericParam, GenericParamKind, WhereClause, -}; +use rustc_ast::{self as ast, AttrVec, GenericBounds, GenericParam, GenericParamKind, WhereClause}; use rustc_errors::{Applicability, PResult}; use rustc_span::symbol::kw; @@ -26,7 +24,7 @@ impl<'a> Parser<'a> { } /// Matches `typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?`. - fn parse_ty_param(&mut self, preceding_attrs: Vec) -> PResult<'a, GenericParam> { + fn parse_ty_param(&mut self, preceding_attrs: AttrVec) -> PResult<'a, GenericParam> { let ident = self.parse_ident()?; // Parse optional colon and param bounds. @@ -43,7 +41,7 @@ impl<'a> Parser<'a> { Ok(GenericParam { ident, id: ast::DUMMY_NODE_ID, - attrs: preceding_attrs.into(), + attrs: preceding_attrs, bounds, kind: GenericParamKind::Type { default }, is_placeholder: false, @@ -53,7 +51,7 @@ impl<'a> Parser<'a> { pub(crate) fn parse_const_param( &mut self, - preceding_attrs: Vec, + preceding_attrs: AttrVec, ) -> PResult<'a, GenericParam> { let const_span = self.token.span; @@ -68,7 +66,7 @@ impl<'a> Parser<'a> { Ok(GenericParam { ident, id: ast::DUMMY_NODE_ID, - attrs: preceding_attrs.into(), + attrs: preceding_attrs, bounds: Vec::new(), kind: GenericParamKind::Const { ty, kw_span: const_span, default }, is_placeholder: false, @@ -109,7 +107,7 @@ impl<'a> Parser<'a> { Some(ast::GenericParam { ident: lifetime.ident, id: lifetime.id, - attrs: attrs.into(), + attrs, bounds, kind: ast::GenericParamKind::Lifetime, is_placeholder: false, diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index cd3c982ce817c..b743162a7e4d0 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -32,7 +32,7 @@ impl<'a> Parser<'a> { } /// Parses a `mod { ... }` or `mod ;` item. - fn parse_item_mod(&mut self, attrs: &mut Vec) -> PResult<'a, ItemInfo> { + fn parse_item_mod(&mut self, attrs: &mut AttrVec) -> PResult<'a, ItemInfo> { let unsafety = self.parse_unsafety(); self.expect_keyword(kw::Mod)?; let id = self.parse_ident()?; @@ -40,9 +40,9 @@ impl<'a> Parser<'a> { ModKind::Unloaded } else { self.expect(&token::OpenDelim(Delimiter::Brace))?; - let (mut inner_attrs, items, inner_span) = + let (inner_attrs, items, inner_span) = self.parse_mod(&token::CloseDelim(Delimiter::Brace))?; - attrs.append(&mut inner_attrs); + attrs.extend(inner_attrs); ModKind::Loaded(items, Inline::Yes, inner_span) }; Ok((id, ItemKind::Mod(unsafety, mod_kind))) @@ -52,7 +52,7 @@ impl<'a> Parser<'a> { pub fn parse_mod( &mut self, term: &TokenKind, - ) -> PResult<'a, (Vec, Vec>, ModSpans)> { + ) -> PResult<'a, (AttrVec, Vec>, ModSpans)> { let lo = self.token.span; let attrs = self.parse_inner_attributes()?; @@ -134,7 +134,7 @@ impl<'a> Parser<'a> { fn parse_item_common_( &mut self, - mut attrs: Vec, + mut attrs: AttrVec, mac_allowed: bool, attrs_allowed: bool, fn_parse_mode: FnParseMode, @@ -198,7 +198,7 @@ impl<'a> Parser<'a> { /// Parses one of the items allowed by the flags. fn parse_item_kind( &mut self, - attrs: &mut Vec, + attrs: &mut AttrVec, macros_allowed: bool, lo: Span, vis: &Visibility, @@ -534,7 +534,7 @@ impl<'a> Parser<'a> { /// ``` fn parse_item_impl( &mut self, - attrs: &mut Vec, + attrs: &mut AttrVec, defaultness: Defaultness, ) -> PResult<'a, ItemInfo> { let unsafety = self.parse_unsafety(); @@ -661,12 +661,12 @@ impl<'a> Parser<'a> { fn parse_item_list( &mut self, - attrs: &mut Vec, + attrs: &mut AttrVec, mut parse_item: impl FnMut(&mut Parser<'a>) -> PResult<'a, Option>>, ) -> PResult<'a, Vec> { let open_brace_span = self.token.span; self.expect(&token::OpenDelim(Delimiter::Brace))?; - attrs.append(&mut self.parse_inner_attributes()?); + attrs.extend(self.parse_inner_attributes()?); let mut items = Vec::new(); while !self.eat(&token::CloseDelim(Delimiter::Brace)) { @@ -775,7 +775,7 @@ impl<'a> Parser<'a> { } /// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`. - fn parse_item_trait(&mut self, attrs: &mut Vec, lo: Span) -> PResult<'a, ItemInfo> { + fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemInfo> { let unsafety = self.parse_unsafety(); // Parse optional `auto` prefix. let is_auto = if self.eat_keyword(kw::Auto) { IsAuto::Yes } else { IsAuto::No }; @@ -1061,7 +1061,7 @@ impl<'a> Parser<'a> { /// ``` fn parse_item_foreign_mod( &mut self, - attrs: &mut Vec, + attrs: &mut AttrVec, mut unsafety: Unsafe, ) -> PResult<'a, ItemInfo> { let abi = self.parse_abi(); // ABI? @@ -1179,7 +1179,7 @@ impl<'a> Parser<'a> { fn recover_const_impl( &mut self, const_span: Span, - attrs: &mut Vec, + attrs: &mut AttrVec, defaultness: Defaultness, ) -> PResult<'a, ItemInfo> { let impl_span = self.token.span; @@ -1337,7 +1337,7 @@ impl<'a> Parser<'a> { ident, vis, id: DUMMY_NODE_ID, - attrs: variant_attrs.into(), + attrs: variant_attrs, data: struct_def, disr_expr, span: vlo.to(this.prev_token.span), @@ -1494,7 +1494,7 @@ impl<'a> Parser<'a> { ident: None, id: DUMMY_NODE_ID, ty, - attrs: attrs.into(), + attrs, is_placeholder: false, }, TrailingToken::MaybeComma, @@ -1520,7 +1520,7 @@ impl<'a> Parser<'a> { adt_ty: &str, lo: Span, vis: Visibility, - attrs: Vec, + attrs: AttrVec, ) -> PResult<'a, FieldDef> { let mut seen_comma: bool = false; let a_var = self.parse_name_and_ty(adt_ty, lo, vis, attrs)?; @@ -1650,7 +1650,7 @@ impl<'a> Parser<'a> { adt_ty: &str, lo: Span, vis: Visibility, - attrs: Vec, + attrs: AttrVec, ) -> PResult<'a, FieldDef> { let name = self.parse_field_ident(adt_ty, lo)?; self.expect_field_ty_separator()?; @@ -1684,7 +1684,7 @@ impl<'a> Parser<'a> { vis, id: DUMMY_NODE_ID, ty, - attrs: attrs.into(), + attrs, is_placeholder: false, }) } @@ -1703,7 +1703,7 @@ impl<'a> Parser<'a> { // We use `parse_fn` to get a span for the function let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true }; if let Err(mut db) = - self.parse_fn(&mut Vec::new(), fn_parse_mode, lo, &inherited_vis) + self.parse_fn(&mut AttrVec::new(), fn_parse_mode, lo, &inherited_vis) { db.delay_as_bug(); } @@ -1979,7 +1979,7 @@ impl<'a> Parser<'a> { /// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`. fn parse_fn( &mut self, - attrs: &mut Vec, + attrs: &mut AttrVec, fn_parse_mode: FnParseMode, sig_lo: Span, vis: &Visibility, @@ -2002,7 +2002,7 @@ impl<'a> Parser<'a> { /// or e.g. a block when the function is a provided one. fn parse_fn_body( &mut self, - attrs: &mut Vec, + attrs: &mut AttrVec, ident: &Ident, sig_hi: &mut Span, req_body: bool, @@ -2017,7 +2017,7 @@ impl<'a> Parser<'a> { // Include the trailing semicolon in the span of the signature self.expect_semi()?; *sig_hi = self.prev_token.span; - (Vec::new(), None) + (AttrVec::new(), None) } else if self.check(&token::OpenDelim(Delimiter::Brace)) || self.token.is_whole_block() { self.parse_inner_attrs_and_block().map(|(attrs, body)| (attrs, Some(body)))? } else if self.token.kind == token::Eq { @@ -2034,7 +2034,7 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ) .emit(); - (Vec::new(), Some(self.mk_block_err(span))) + (AttrVec::new(), Some(self.mk_block_err(span))) } else { let expected = if req_body { &[token::OpenDelim(Delimiter::Brace)][..] @@ -2051,7 +2051,7 @@ impl<'a> Parser<'a> { return Err(err); } } - (Vec::new(), None) + (AttrVec::new(), None) }; attrs.extend(inner_attrs); Ok(body) @@ -2280,7 +2280,7 @@ impl<'a> Parser<'a> { self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here. if let Some(mut param) = this.parse_self_param()? { - param.attrs = attrs.into(); + param.attrs = attrs; let res = if first_param { Ok(param) } else { this.recover_bad_self_param(param) }; return Ok((res?, TrailingToken::None)); } @@ -2341,14 +2341,7 @@ impl<'a> Parser<'a> { let span = lo.to(this.prev_token.span); Ok(( - Param { - attrs: attrs.into(), - id: ast::DUMMY_NODE_ID, - is_placeholder: false, - pat, - span, - ty, - }, + Param { attrs, id: ast::DUMMY_NODE_ID, is_placeholder: false, pat, span, ty }, TrailingToken::None, )) }) diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 42bf889844710..8b3200d45fccd 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -4,8 +4,8 @@ use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor}; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter}; use rustc_ast::{ - self as ast, Attribute, BindingMode, Expr, ExprKind, MacCall, Mutability, Pat, PatField, - PatKind, Path, QSelf, RangeEnd, RangeSyntax, + self as ast, AttrVec, BindingMode, Expr, ExprKind, MacCall, Mutability, Pat, PatField, PatKind, + Path, QSelf, RangeEnd, RangeSyntax, }; use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult}; @@ -1093,7 +1093,7 @@ impl<'a> Parser<'a> { .emit(); } - fn parse_pat_field(&mut self, lo: Span, attrs: Vec) -> PResult<'a, PatField> { + fn parse_pat_field(&mut self, lo: Span, attrs: AttrVec) -> PResult<'a, PatField> { // Check if a colon exists one ahead. This means we're parsing a fieldname. let hi; let (subpat, fieldname, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) { @@ -1134,7 +1134,7 @@ impl<'a> Parser<'a> { ident: fieldname, pat: subpat, is_shorthand, - attrs: attrs.into(), + attrs, id: ast::DUMMY_NODE_ID, span: lo.to(hi), is_placeholder: false, diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 12b1a37e02247..3d957406b19d8 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -130,7 +130,7 @@ impl<'a> Parser<'a> { let path = this.parse_path(PathStyle::Expr)?; if this.eat(&token::Not) { - let stmt_mac = this.parse_stmt_mac(lo, attrs.into(), path)?; + let stmt_mac = this.parse_stmt_mac(lo, attrs, path)?; if this.token == token::Semi { return Ok((stmt_mac, TrailingToken::Semi)); } else { @@ -190,7 +190,7 @@ impl<'a> Parser<'a> { // Since none of the above applied, this is an expression statement macro. let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac)); let e = self.maybe_recover_from_bad_qpath(e)?; - let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?; + let e = self.parse_dot_or_call_expr_with(e, lo, attrs)?; let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?; StmtKind::Expr(e) }; @@ -229,7 +229,7 @@ impl<'a> Parser<'a> { ) -> PResult<'a, Stmt> { self.collect_tokens_trailing_token(attrs, force_collect, |this, attrs| { this.expect_keyword(kw::Let)?; - let local = this.parse_local(attrs.into())?; + let local = this.parse_local(attrs)?; let trailing = if capture_semi && this.token.kind == token::Semi { TrailingToken::Semi } else { @@ -241,7 +241,7 @@ impl<'a> Parser<'a> { fn recover_local_after_let(&mut self, lo: Span, attrs: AttrWrapper) -> PResult<'a, Stmt> { self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { - let local = this.parse_local(attrs.into())?; + let local = this.parse_local(attrs)?; // FIXME - maybe capture semicolon in recovery? Ok(( this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Local(local)), @@ -509,9 +509,7 @@ impl<'a> Parser<'a> { } /// Parses a block. Inner attributes are allowed. - pub(super) fn parse_inner_attrs_and_block( - &mut self, - ) -> PResult<'a, (Vec, P)> { + pub(super) fn parse_inner_attrs_and_block(&mut self) -> PResult<'a, (AttrVec, P)> { self.parse_block_common(self.token.span, BlockCheckMode::Default) } @@ -520,8 +518,8 @@ impl<'a> Parser<'a> { &mut self, lo: Span, blk_mode: BlockCheckMode, - ) -> PResult<'a, (Vec, P)> { - maybe_whole!(self, NtBlock, |x| (Vec::new(), x)); + ) -> PResult<'a, (AttrVec, P)> { + maybe_whole!(self, NtBlock, |x| (AttrVec::new(), x)); self.maybe_recover_unexpected_block_label(); if !self.eat(&token::OpenDelim(Delimiter::Brace)) { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index cd465380867cf..383982013d9e7 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -3,37 +3,37 @@ use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_span::{Span, Symbol}; #[derive(LintDiagnostic)] -#[lint(passes::outer_crate_level_attr)] +#[diag(passes::outer_crate_level_attr)] pub struct OuterCrateLevelAttr; #[derive(LintDiagnostic)] -#[lint(passes::inner_crate_level_attr)] +#[diag(passes::inner_crate_level_attr)] pub struct InnerCrateLevelAttr; #[derive(LintDiagnostic)] -#[lint(passes::ignored_attr_with_macro)] +#[diag(passes::ignored_attr_with_macro)] pub struct IgnoredAttrWithMacro<'a> { pub sym: &'a str, } #[derive(LintDiagnostic)] -#[lint(passes::ignored_attr)] +#[diag(passes::ignored_attr)] pub struct IgnoredAttr<'a> { pub sym: &'a str, } #[derive(LintDiagnostic)] -#[lint(passes::inline_ignored_function_prototype)] +#[diag(passes::inline_ignored_function_prototype)] pub struct IgnoredInlineAttrFnProto; #[derive(LintDiagnostic)] -#[lint(passes::inline_ignored_constants)] +#[diag(passes::inline_ignored_constants)] #[warn_] #[note] pub struct IgnoredInlineAttrConstants; #[derive(SessionDiagnostic)] -#[error(passes::inline_not_fn_or_closure, code = "E0518")] +#[diag(passes::inline_not_fn_or_closure, code = "E0518")] pub struct InlineNotFnOrClosure { #[primary_span] pub attr_span: Span, @@ -42,19 +42,19 @@ pub struct InlineNotFnOrClosure { } #[derive(LintDiagnostic)] -#[lint(passes::no_coverage_ignored_function_prototype)] +#[diag(passes::no_coverage_ignored_function_prototype)] pub struct IgnoredNoCoverageFnProto; #[derive(LintDiagnostic)] -#[lint(passes::no_coverage_propagate)] +#[diag(passes::no_coverage_propagate)] pub struct IgnoredNoCoveragePropagate; #[derive(LintDiagnostic)] -#[lint(passes::no_coverage_fn_defn)] +#[diag(passes::no_coverage_fn_defn)] pub struct IgnoredNoCoverageFnDefn; #[derive(SessionDiagnostic)] -#[error(passes::no_coverage_not_coverable, code = "E0788")] +#[diag(passes::no_coverage_not_coverable, code = "E0788")] pub struct IgnoredNoCoverageNotCoverable { #[primary_span] pub attr_span: Span, @@ -63,7 +63,7 @@ pub struct IgnoredNoCoverageNotCoverable { } #[derive(SessionDiagnostic)] -#[error(passes::should_be_applied_to_fn)] +#[diag(passes::should_be_applied_to_fn)] pub struct AttrShouldBeAppliedToFn { #[primary_span] pub attr_span: Span, @@ -72,14 +72,14 @@ pub struct AttrShouldBeAppliedToFn { } #[derive(SessionDiagnostic)] -#[error(passes::naked_tracked_caller, code = "E0736")] +#[diag(passes::naked_tracked_caller, code = "E0736")] pub struct NakedTrackedCaller { #[primary_span] pub attr_span: Span, } #[derive(SessionDiagnostic)] -#[error(passes::should_be_applied_to_fn, code = "E0739")] +#[diag(passes::should_be_applied_to_fn, code = "E0739")] pub struct TrackedCallerWrongLocation { #[primary_span] pub attr_span: Span, @@ -88,7 +88,7 @@ pub struct TrackedCallerWrongLocation { } #[derive(SessionDiagnostic)] -#[error(passes::should_be_applied_to_struct_enum, code = "E0701")] +#[diag(passes::should_be_applied_to_struct_enum, code = "E0701")] pub struct NonExhaustiveWrongLocation { #[primary_span] pub attr_span: Span, @@ -97,7 +97,7 @@ pub struct NonExhaustiveWrongLocation { } #[derive(SessionDiagnostic)] -#[error(passes::should_be_applied_to_trait)] +#[diag(passes::should_be_applied_to_trait)] pub struct AttrShouldBeAppliedToTrait { #[primary_span] pub attr_span: Span, @@ -106,11 +106,11 @@ pub struct AttrShouldBeAppliedToTrait { } #[derive(LintDiagnostic)] -#[lint(passes::target_feature_on_statement)] +#[diag(passes::target_feature_on_statement)] pub struct TargetFeatureOnStatement; #[derive(SessionDiagnostic)] -#[error(passes::should_be_applied_to_static)] +#[diag(passes::should_be_applied_to_static)] pub struct AttrShouldBeAppliedToStatic { #[primary_span] pub attr_span: Span, @@ -119,7 +119,7 @@ pub struct AttrShouldBeAppliedToStatic { } #[derive(SessionDiagnostic)] -#[error(passes::doc_expect_str)] +#[diag(passes::doc_expect_str)] pub struct DocExpectStr<'a> { #[primary_span] pub attr_span: Span, @@ -127,7 +127,7 @@ pub struct DocExpectStr<'a> { } #[derive(SessionDiagnostic)] -#[error(passes::doc_alias_empty)] +#[diag(passes::doc_alias_empty)] pub struct DocAliasEmpty<'a> { #[primary_span] pub span: Span, @@ -135,7 +135,7 @@ pub struct DocAliasEmpty<'a> { } #[derive(SessionDiagnostic)] -#[error(passes::doc_alias_bad_char)] +#[diag(passes::doc_alias_bad_char)] pub struct DocAliasBadChar<'a> { #[primary_span] pub span: Span, @@ -144,7 +144,7 @@ pub struct DocAliasBadChar<'a> { } #[derive(SessionDiagnostic)] -#[error(passes::doc_alias_start_end)] +#[diag(passes::doc_alias_start_end)] pub struct DocAliasStartEnd<'a> { #[primary_span] pub span: Span, @@ -152,7 +152,7 @@ pub struct DocAliasStartEnd<'a> { } #[derive(SessionDiagnostic)] -#[error(passes::doc_alias_bad_location)] +#[diag(passes::doc_alias_bad_location)] pub struct DocAliasBadLocation<'a> { #[primary_span] pub span: Span, @@ -161,7 +161,7 @@ pub struct DocAliasBadLocation<'a> { } #[derive(SessionDiagnostic)] -#[error(passes::doc_alias_not_an_alias)] +#[diag(passes::doc_alias_not_an_alias)] pub struct DocAliasNotAnAlias<'a> { #[primary_span] pub span: Span, @@ -169,42 +169,42 @@ pub struct DocAliasNotAnAlias<'a> { } #[derive(LintDiagnostic)] -#[lint(passes::doc_alias_duplicated)] +#[diag(passes::doc_alias_duplicated)] pub struct DocAliasDuplicated { #[label] pub first_defn: Span, } #[derive(SessionDiagnostic)] -#[error(passes::doc_alias_not_string_literal)] +#[diag(passes::doc_alias_not_string_literal)] pub struct DocAliasNotStringLiteral { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(passes::doc_alias_malformed)] +#[diag(passes::doc_alias_malformed)] pub struct DocAliasMalformed { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(passes::doc_keyword_empty_mod)] +#[diag(passes::doc_keyword_empty_mod)] pub struct DocKeywordEmptyMod { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(passes::doc_keyword_not_mod)] +#[diag(passes::doc_keyword_not_mod)] pub struct DocKeywordNotMod { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(passes::doc_keyword_invalid_ident)] +#[diag(passes::doc_keyword_invalid_ident)] pub struct DocKeywordInvalidIdent { #[primary_span] pub span: Span, @@ -212,21 +212,21 @@ pub struct DocKeywordInvalidIdent { } #[derive(SessionDiagnostic)] -#[error(passes::doc_fake_variadic_not_valid)] +#[diag(passes::doc_fake_variadic_not_valid)] pub struct DocFakeVariadicNotValid { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(passes::doc_keyword_only_impl)] +#[diag(passes::doc_keyword_only_impl)] pub struct DocKeywordOnlyImpl { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(passes::doc_inline_conflict)] +#[diag(passes::doc_inline_conflict)] #[help] pub struct DocKeywordConflict { #[primary_span] @@ -234,7 +234,7 @@ pub struct DocKeywordConflict { } #[derive(LintDiagnostic)] -#[lint(passes::doc_inline_only_use)] +#[diag(passes::doc_inline_only_use)] #[note] pub struct DocInlineOnlyUse { #[label] @@ -244,7 +244,7 @@ pub struct DocInlineOnlyUse { } #[derive(SessionDiagnostic)] -#[error(passes::doc_attr_not_crate_level)] +#[diag(passes::doc_attr_not_crate_level)] pub struct DocAttrNotCrateLevel<'a> { #[primary_span] pub span: Span, @@ -252,27 +252,27 @@ pub struct DocAttrNotCrateLevel<'a> { } #[derive(LintDiagnostic)] -#[lint(passes::doc_test_unknown)] +#[diag(passes::doc_test_unknown)] pub struct DocTestUnknown { pub path: String, } #[derive(LintDiagnostic)] -#[lint(passes::doc_test_takes_list)] +#[diag(passes::doc_test_takes_list)] pub struct DocTestTakesList; #[derive(LintDiagnostic)] -#[lint(passes::doc_primitive)] +#[diag(passes::doc_primitive)] pub struct DocPrimitive; #[derive(LintDiagnostic)] -#[lint(passes::doc_test_unknown_any)] +#[diag(passes::doc_test_unknown_any)] pub struct DocTestUnknownAny { pub path: String, } #[derive(LintDiagnostic)] -#[lint(passes::doc_test_unknown_spotlight)] +#[diag(passes::doc_test_unknown_spotlight)] #[note] #[note(passes::no_op_note)] pub struct DocTestUnknownSpotlight { @@ -282,7 +282,7 @@ pub struct DocTestUnknownSpotlight { } #[derive(LintDiagnostic)] -#[lint(passes::doc_test_unknown_include)] +#[diag(passes::doc_test_unknown_include)] pub struct DocTestUnknownInclude { pub path: String, pub value: String, @@ -292,11 +292,11 @@ pub struct DocTestUnknownInclude { } #[derive(LintDiagnostic)] -#[lint(passes::doc_invalid)] +#[diag(passes::doc_invalid)] pub struct DocInvalid; #[derive(SessionDiagnostic)] -#[error(passes::pass_by_value)] +#[diag(passes::pass_by_value)] pub struct PassByValue { #[primary_span] pub attr_span: Span, @@ -305,7 +305,7 @@ pub struct PassByValue { } #[derive(SessionDiagnostic)] -#[error(passes::allow_incoherent_impl)] +#[diag(passes::allow_incoherent_impl)] pub struct AllowIncoherentImpl { #[primary_span] pub attr_span: Span, @@ -314,7 +314,7 @@ pub struct AllowIncoherentImpl { } #[derive(SessionDiagnostic)] -#[error(passes::has_incoherent_inherent_impl)] +#[diag(passes::has_incoherent_inherent_impl)] pub struct HasIncoherentInherentImpl { #[primary_span] pub attr_span: Span, @@ -323,21 +323,21 @@ pub struct HasIncoherentInherentImpl { } #[derive(LintDiagnostic)] -#[lint(passes::must_use_async)] +#[diag(passes::must_use_async)] pub struct MustUseAsync { #[label] pub span: Span, } #[derive(LintDiagnostic)] -#[lint(passes::must_use_no_effect)] +#[diag(passes::must_use_no_effect)] pub struct MustUseNoEffect { pub article: &'static str, pub target: rustc_hir::Target, } #[derive(SessionDiagnostic)] -#[error(passes::must_not_suspend)] +#[diag(passes::must_not_suspend)] pub struct MustNotSuspend { #[primary_span] pub attr_span: Span, @@ -346,7 +346,7 @@ pub struct MustNotSuspend { } #[derive(LintDiagnostic)] -#[lint(passes::cold)] +#[diag(passes::cold)] #[warn_] pub struct Cold { #[label] @@ -354,7 +354,7 @@ pub struct Cold { } #[derive(LintDiagnostic)] -#[lint(passes::link)] +#[diag(passes::link)] #[warn_] pub struct Link { #[label] @@ -362,7 +362,7 @@ pub struct Link { } #[derive(LintDiagnostic)] -#[lint(passes::link_name)] +#[diag(passes::link_name)] #[warn_] pub struct LinkName<'a> { #[help] @@ -373,7 +373,7 @@ pub struct LinkName<'a> { } #[derive(SessionDiagnostic)] -#[error(passes::no_link)] +#[diag(passes::no_link)] pub struct NoLink { #[primary_span] pub attr_span: Span, @@ -382,7 +382,7 @@ pub struct NoLink { } #[derive(SessionDiagnostic)] -#[error(passes::export_name)] +#[diag(passes::export_name)] pub struct ExportName { #[primary_span] pub attr_span: Span, @@ -391,7 +391,7 @@ pub struct ExportName { } #[derive(SessionDiagnostic)] -#[error(passes::rustc_layout_scalar_valid_range_not_struct)] +#[diag(passes::rustc_layout_scalar_valid_range_not_struct)] pub struct RustcLayoutScalarValidRangeNotStruct { #[primary_span] pub attr_span: Span, @@ -400,14 +400,14 @@ pub struct RustcLayoutScalarValidRangeNotStruct { } #[derive(SessionDiagnostic)] -#[error(passes::rustc_layout_scalar_valid_range_arg)] +#[diag(passes::rustc_layout_scalar_valid_range_arg)] pub struct RustcLayoutScalarValidRangeArg { #[primary_span] pub attr_span: Span, } #[derive(SessionDiagnostic)] -#[error(passes::rustc_legacy_const_generics_only)] +#[diag(passes::rustc_legacy_const_generics_only)] pub struct RustcLegacyConstGenericsOnly { #[primary_span] pub attr_span: Span, @@ -416,7 +416,7 @@ pub struct RustcLegacyConstGenericsOnly { } #[derive(SessionDiagnostic)] -#[error(passes::rustc_legacy_const_generics_index)] +#[diag(passes::rustc_legacy_const_generics_index)] pub struct RustcLegacyConstGenericsIndex { #[primary_span] pub attr_span: Span, @@ -425,7 +425,7 @@ pub struct RustcLegacyConstGenericsIndex { } #[derive(SessionDiagnostic)] -#[error(passes::rustc_legacy_const_generics_index_exceed)] +#[diag(passes::rustc_legacy_const_generics_index_exceed)] pub struct RustcLegacyConstGenericsIndexExceed { #[primary_span] #[label] @@ -434,21 +434,21 @@ pub struct RustcLegacyConstGenericsIndexExceed { } #[derive(SessionDiagnostic)] -#[error(passes::rustc_legacy_const_generics_index_negative)] +#[diag(passes::rustc_legacy_const_generics_index_negative)] pub struct RustcLegacyConstGenericsIndexNegative { #[primary_span] pub invalid_args: Vec, } #[derive(SessionDiagnostic)] -#[error(passes::rustc_dirty_clean)] +#[diag(passes::rustc_dirty_clean)] pub struct RustcDirtyClean { #[primary_span] pub span: Span, } #[derive(LintDiagnostic)] -#[lint(passes::link_section)] +#[diag(passes::link_section)] #[warn_] pub struct LinkSection { #[label] @@ -456,7 +456,7 @@ pub struct LinkSection { } #[derive(LintDiagnostic)] -#[lint(passes::no_mangle_foreign)] +#[diag(passes::no_mangle_foreign)] #[warn_] #[note] pub struct NoMangleForeign { @@ -468,7 +468,7 @@ pub struct NoMangleForeign { } #[derive(LintDiagnostic)] -#[lint(passes::no_mangle)] +#[diag(passes::no_mangle)] #[warn_] pub struct NoMangle { #[label] @@ -476,32 +476,32 @@ pub struct NoMangle { } #[derive(SessionDiagnostic)] -#[error(passes::repr_ident, code = "E0565")] +#[diag(passes::repr_ident, code = "E0565")] pub struct ReprIdent { #[primary_span] pub span: Span, } #[derive(LintDiagnostic)] -#[lint(passes::repr_conflicting, code = "E0566")] +#[diag(passes::repr_conflicting, code = "E0566")] pub struct ReprConflicting; #[derive(SessionDiagnostic)] -#[error(passes::used_static)] +#[diag(passes::used_static)] pub struct UsedStatic { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(passes::used_compiler_linker)] +#[diag(passes::used_compiler_linker)] pub struct UsedCompilerLinker { #[primary_span] pub spans: Vec, } #[derive(SessionDiagnostic)] -#[error(passes::allow_internal_unstable)] +#[diag(passes::allow_internal_unstable)] pub struct AllowInternalUnstable { #[primary_span] pub attr_span: Span, @@ -510,14 +510,14 @@ pub struct AllowInternalUnstable { } #[derive(SessionDiagnostic)] -#[error(passes::debug_visualizer_placement)] +#[diag(passes::debug_visualizer_placement)] pub struct DebugVisualizerPlacement { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(passes::debug_visualizer_invalid)] +#[diag(passes::debug_visualizer_invalid)] #[note(passes::note_1)] #[note(passes::note_2)] #[note(passes::note_3)] @@ -527,7 +527,7 @@ pub struct DebugVisualizerInvalid { } #[derive(SessionDiagnostic)] -#[error(passes::rustc_allow_const_fn_unstable)] +#[diag(passes::rustc_allow_const_fn_unstable)] pub struct RustcAllowConstFnUnstable { #[primary_span] pub attr_span: Span, @@ -536,7 +536,7 @@ pub struct RustcAllowConstFnUnstable { } #[derive(SessionDiagnostic)] -#[error(passes::rustc_std_internal_symbol)] +#[diag(passes::rustc_std_internal_symbol)] pub struct RustcStdInternalSymbol { #[primary_span] pub attr_span: Span, @@ -545,42 +545,42 @@ pub struct RustcStdInternalSymbol { } #[derive(SessionDiagnostic)] -#[error(passes::const_trait)] +#[diag(passes::const_trait)] pub struct ConstTrait { #[primary_span] pub attr_span: Span, } #[derive(SessionDiagnostic)] -#[error(passes::link_ordinal)] +#[diag(passes::link_ordinal)] pub struct LinkOrdinal { #[primary_span] pub attr_span: Span, } #[derive(SessionDiagnostic)] -#[error(passes::stability_promotable)] +#[diag(passes::stability_promotable)] pub struct StabilityPromotable { #[primary_span] pub attr_span: Span, } #[derive(LintDiagnostic)] -#[lint(passes::deprecated)] +#[diag(passes::deprecated)] pub struct Deprecated; #[derive(LintDiagnostic)] -#[lint(passes::macro_use)] +#[diag(passes::macro_use)] pub struct MacroUse { pub name: Symbol, } #[derive(LintDiagnostic)] -#[lint(passes::macro_export)] +#[diag(passes::macro_export)] pub struct MacroExport; #[derive(LintDiagnostic)] -#[lint(passes::plugin_registrar)] +#[diag(passes::plugin_registrar)] pub struct PluginRegistrar; #[derive(SessionSubdiagnostic)] @@ -594,7 +594,7 @@ pub enum UnusedNote { } #[derive(LintDiagnostic)] -#[lint(passes::unused)] +#[diag(passes::unused)] pub struct Unused { #[suggestion(applicability = "machine-applicable")] pub attr_span: Span, @@ -603,7 +603,7 @@ pub struct Unused { } #[derive(SessionDiagnostic)] -#[error(passes::non_exported_macro_invalid_attrs, code = "E0518")] +#[diag(passes::non_exported_macro_invalid_attrs, code = "E0518")] pub struct NonExportedMacroInvalidAttrs { #[primary_span] #[label] @@ -611,9 +611,8 @@ pub struct NonExportedMacroInvalidAttrs { } #[derive(LintDiagnostic)] -#[lint(passes::unused_duplicate)] +#[diag(passes::unused_duplicate)] pub struct UnusedDuplicate { - #[primary_span] #[suggestion(code = "", applicability = "machine-applicable")] pub this: Span, #[note] @@ -623,7 +622,7 @@ pub struct UnusedDuplicate { } #[derive(SessionDiagnostic)] -#[error(passes::unused_multiple)] +#[diag(passes::unused_multiple)] pub struct UnusedMultiple { #[primary_span] #[suggestion(code = "", applicability = "machine-applicable")] @@ -634,7 +633,7 @@ pub struct UnusedMultiple { } #[derive(SessionDiagnostic)] -#[error(passes::rustc_lint_opt_ty)] +#[diag(passes::rustc_lint_opt_ty)] pub struct RustcLintOptTy { #[primary_span] pub attr_span: Span, @@ -643,7 +642,7 @@ pub struct RustcLintOptTy { } #[derive(SessionDiagnostic)] -#[error(passes::rustc_lint_opt_deny_field_access)] +#[diag(passes::rustc_lint_opt_deny_field_access)] pub struct RustcLintOptDenyFieldAccess { #[primary_span] pub attr_span: Span, diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index aca7d770f3495..1e423ddb7102c 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -3,7 +3,7 @@ use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_span::{Span, Symbol}; #[derive(SessionDiagnostic)] -#[error(privacy::field_is_private, code = "E0451")] +#[diag(privacy::field_is_private, code = "E0451")] pub struct FieldIsPrivate { #[primary_span] pub span: Span, @@ -30,7 +30,7 @@ pub enum FieldIsPrivateLabel { } #[derive(SessionDiagnostic)] -#[error(privacy::item_is_private)] +#[diag(privacy::item_is_private)] pub struct ItemIsPrivate<'a> { #[primary_span] #[label] @@ -40,7 +40,7 @@ pub struct ItemIsPrivate<'a> { } #[derive(SessionDiagnostic)] -#[error(privacy::unnamed_item_is_private)] +#[diag(privacy::unnamed_item_is_private)] pub struct UnnamedItemIsPrivate { #[primary_span] pub span: Span, @@ -49,7 +49,7 @@ pub struct UnnamedItemIsPrivate { // Duplicate of `InPublicInterface` but with a different error code, shares the same slug. #[derive(SessionDiagnostic)] -#[error(privacy::in_public_interface, code = "E0445")] +#[diag(privacy::in_public_interface, code = "E0445")] pub struct InPublicInterfaceTraits<'a> { #[primary_span] #[label] @@ -63,7 +63,7 @@ pub struct InPublicInterfaceTraits<'a> { // Duplicate of `InPublicInterfaceTraits` but with a different error code, shares the same slug. #[derive(SessionDiagnostic)] -#[error(privacy::in_public_interface, code = "E0446")] +#[diag(privacy::in_public_interface, code = "E0446")] pub struct InPublicInterface<'a> { #[primary_span] #[label] @@ -76,7 +76,7 @@ pub struct InPublicInterface<'a> { } #[derive(LintDiagnostic)] -#[lint(privacy::from_private_dep_in_public_interface)] +#[diag(privacy::from_private_dep_in_public_interface)] pub struct FromPrivateDependencyInPublicInterface<'a> { pub kind: &'a str, pub descr: DiagnosticArgFromDisplay<'a>, @@ -84,7 +84,7 @@ pub struct FromPrivateDependencyInPublicInterface<'a> { } #[derive(LintDiagnostic)] -#[lint(privacy::private_in_public_lint)] +#[diag(privacy::private_in_public_lint)] pub struct PrivateInPublicLint<'a> { pub vis_descr: &'static str, pub kind: &'a str, diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index 36585b8d77e0a..9bd5550038fc6 100644 --- a/compiler/rustc_serialize/src/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs @@ -273,7 +273,7 @@ impl> Decodable for Vec { unsafe { let ptr: *mut T = vec.as_mut_ptr(); for i in 0..len { - std::ptr::write(ptr.offset(i as isize), Decodable::decode(d)); + std::ptr::write(ptr.add(i), Decodable::decode(d)); } vec.set_len(len); } diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 9f0886cb2089c..b9b2356130a59 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -12,7 +12,7 @@ use rustc_data_structures::sync::{Lock, Lrc}; use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler}; use rustc_errors::{ error_code, fallback_fluent_bundle, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId, - DiagnosticMessage, ErrorGuaranteed, MultiSpan, StashKey, + DiagnosticMessage, EmissionGuarantee, ErrorGuaranteed, MultiSpan, StashKey, }; use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures}; use rustc_span::edition::Edition; @@ -372,4 +372,12 @@ impl ParseSess { pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { self.span_diagnostic.struct_warn(msg) } + + #[rustc_lint_diagnostics] + pub fn struct_diagnostic( + &self, + msg: impl Into, + ) -> DiagnosticBuilder<'_, G> { + self.span_diagnostic.struct_diagnostic(msg) + } } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index d14e28e85be1a..860af7fe93a07 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -664,6 +664,16 @@ impl Span { Some(self) } + /// Like `find_ancestor_inside`, but specifically for when spans might not + /// overlaps. Take care when using this, and prefer `find_ancestor_inside` + /// when you know that the spans are nested (modulo macro expansion). + pub fn find_ancestor_in_same_ctxt(mut self, other: Span) -> Option { + while !Span::eq_ctxt(self, other) { + self = self.parent_callsite()?; + } + Some(self) + } + /// Edition of the crate from which this span came. pub fn edition(self) -> edition::Edition { self.ctxt().edition() diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 1a39a1680384d..70fac83325a9c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -860,8 +860,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } } - err.emit(); - return; + err } ty::PredicateKind::WellFormed(ty) => { @@ -1564,6 +1563,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { obligation.cause.code().peel_derives(), ObligationCauseCode::ItemObligation(_) | ObligationCauseCode::BindingObligation(_, _) + | ObligationCauseCode::ExprItemObligation(..) + | ObligationCauseCode::ExprBindingObligation(..) | ObligationCauseCode::ObjectCastObligation(..) | ObligationCauseCode::OpaqueType ); @@ -2091,13 +2092,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { } } - if let ObligationCauseCode::ItemObligation(def_id) = *obligation.cause.code() { + if let ObligationCauseCode::ItemObligation(def_id) | ObligationCauseCode::ExprItemObligation(def_id, ..) = *obligation.cause.code() { self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); - } else if let ( - Ok(ref snippet), - &ObligationCauseCode::BindingObligation(def_id, _), - ) = - (self.tcx.sess.source_map().span_to_snippet(span), obligation.cause.code()) + } else if let Ok(snippet) = &self.tcx.sess.source_map().span_to_snippet(span) + && let ObligationCauseCode::BindingObligation(def_id, _) | ObligationCauseCode::ExprBindingObligation(def_id, ..) + = *obligation.cause.code() { let generics = self.tcx.generics_of(def_id); if generics.params.iter().any(|p| p.name != kw::SelfUpper) @@ -2520,15 +2519,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>, ) { - let ( - ty::PredicateKind::Trait(pred), - &ObligationCauseCode::BindingObligation(item_def_id, span), - ) = ( - obligation.predicate.kind().skip_binder(), - obligation.cause.code().peel_derives(), - ) else { - return; - }; + let ty::PredicateKind::Trait(pred) = obligation.predicate.kind().skip_binder() else { return; }; + let (ObligationCauseCode::BindingObligation(item_def_id, span) + | ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..)) + = *obligation.cause.code().peel_derives() else { return; }; debug!(?pred, ?item_def_id, ?span); let (Some(node), true) = ( diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index e6907637c57b6..6b03555bc6985 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -143,7 +143,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } if let ObligationCauseCode::ItemObligation(item) - | ObligationCauseCode::BindingObligation(item, _) = *obligation.cause.code() + | ObligationCauseCode::BindingObligation(item, _) + | ObligationCauseCode::ExprItemObligation(item, ..) + | ObligationCauseCode::ExprBindingObligation(item, ..) = *obligation.cause.code() { // FIXME: maybe also have some way of handling methods // from other traits? That would require name resolution, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 0d279069694a9..a93f9ec0397d2 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -671,11 +671,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> bool { // It only make sense when suggesting dereferences for arguments - let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() else { - return false; - }; - let param_env = obligation.param_env; - let body_id = obligation.cause.body_id; + let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() + else { return false; }; + let Some(typeck_results) = self.in_progress_typeck_results + else { return false; }; + let typeck_results = typeck_results.borrow(); + let hir::Node::Expr(expr) = self.tcx.hir().get(*arg_hir_id) + else { return false; }; + let Some(arg_ty) = typeck_results.expr_ty_adjusted_opt(expr) + else { return false; }; + let span = obligation.cause.span; let mut real_trait_pred = trait_pred; let mut code = obligation.cause.code(); @@ -687,9 +692,19 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // Skipping binder here, remapping below let real_ty = real_trait_pred.self_ty().skip_binder(); + if self.can_eq(obligation.param_env, real_ty, arg_ty).is_err() { + continue; + } if let ty::Ref(region, base_ty, mutbl) = *real_ty.kind() { - let mut autoderef = Autoderef::new(self, param_env, body_id, span, base_ty, span); + let mut autoderef = Autoderef::new( + self, + obligation.param_env, + obligation.cause.body_id, + span, + base_ty, + span, + ); if let Some(steps) = autoderef.find_map(|(ty, steps)| { // Re-add the `&` let ty = self.tcx.mk_ref(region, TypeAndMut { ty, mutbl }); @@ -697,8 +712,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // Remapping bound vars here let real_trait_pred_and_ty = real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, ty)); - let obligation = self - .mk_trait_obligation_with_new_self_ty(param_env, real_trait_pred_and_ty); + let obligation = self.mk_trait_obligation_with_new_self_ty( + obligation.param_env, + real_trait_pred_and_ty, + ); Some(steps).filter(|_| self.predicate_may_hold(&obligation)) }) { if steps > 0 { @@ -727,7 +744,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let real_trait_pred_and_base_ty = real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, base_ty)); let obligation = self.mk_trait_obligation_with_new_self_ty( - param_env, + obligation.param_env, real_trait_pred_and_base_ty, ); if self.predicate_may_hold(&obligation) { @@ -855,6 +872,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { _ => return false, }; if matches!(obligation.cause.code(), ObligationCauseCode::FunctionArgumentObligation { .. }) + && obligation.cause.span.can_be_used_for_suggestions() { // When the obligation error has been ensured to have been caused by // an argument, the `obligation.cause.span` points at the expression @@ -885,7 +903,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { obligation.cause.code() { &parent_code - } else if let ObligationCauseCode::ItemObligation(_) = obligation.cause.code() { + } else if let ObligationCauseCode::ItemObligation(_) + | ObligationCauseCode::ExprItemObligation(..) = obligation.cause.code() + { obligation.cause.code() } else if let ExpnKind::Desugaring(DesugaringKind::ForLoop) = span.ctxt().outer_expn_data().kind @@ -911,35 +931,36 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let param_env = obligation.param_env; // Try to apply the original trait binding obligation by borrowing. - let mut try_borrowing = - |old_pred: ty::PolyTraitPredicate<'tcx>, blacklist: &[DefId]| -> bool { - if blacklist.contains(&old_pred.def_id()) { - return false; - } - // We map bounds to `&T` and `&mut T` - let trait_pred_and_imm_ref = old_pred.map_bound(|trait_pred| { - ( - trait_pred, - self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()), - ) - }); - let trait_pred_and_mut_ref = old_pred.map_bound(|trait_pred| { - ( - trait_pred, - self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()), - ) - }); + let mut try_borrowing = |old_pred: ty::PolyTraitPredicate<'tcx>, + blacklist: &[DefId]| + -> bool { + if blacklist.contains(&old_pred.def_id()) { + return false; + } + // We map bounds to `&T` and `&mut T` + let trait_pred_and_imm_ref = old_pred.map_bound(|trait_pred| { + ( + trait_pred, + self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()), + ) + }); + let trait_pred_and_mut_ref = old_pred.map_bound(|trait_pred| { + ( + trait_pred, + self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()), + ) + }); - let mk_result = |trait_pred_and_new_ty| { - let obligation = - self.mk_trait_obligation_with_new_self_ty(param_env, trait_pred_and_new_ty); - self.predicate_must_hold_modulo_regions(&obligation) - }; - let imm_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_imm_ref); - let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref); + let mk_result = |trait_pred_and_new_ty| { + let obligation = + self.mk_trait_obligation_with_new_self_ty(param_env, trait_pred_and_new_ty); + self.predicate_must_hold_modulo_regions(&obligation) + }; + let imm_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_imm_ref); + let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref); - let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) = - if let ObligationCauseCode::ItemObligation(_) = obligation.cause.code() + let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) = + if let ObligationCauseCode::ItemObligation(_) | ObligationCauseCode::ExprItemObligation(..) = obligation.cause.code() && let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind() { ( @@ -950,79 +971,81 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { (false, false) }; - if imm_ref_self_ty_satisfies_pred - || mut_ref_self_ty_satisfies_pred - || ref_inner_ty_satisfies_pred - { - if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { - // We have a very specific type of error, where just borrowing this argument - // might solve the problem. In cases like this, the important part is the - // original type obligation, not the last one that failed, which is arbitrary. - // Because of this, we modify the error to refer to the original obligation and - // return early in the caller. - - let msg = format!("the trait bound `{}` is not satisfied", old_pred); - if has_custom_message { - err.note(&msg); - } else { - err.message = - vec![(rustc_errors::DiagnosticMessage::Str(msg), Style::NoStyle)]; - } - if snippet.starts_with('&') { - // This is already a literal borrow and the obligation is failing - // somewhere else in the obligation chain. Do not suggest non-sense. - return false; - } - err.span_label( - span, + if imm_ref_self_ty_satisfies_pred + || mut_ref_self_ty_satisfies_pred + || ref_inner_ty_satisfies_pred + { + if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { + // We don't want a borrowing suggestion on the fields in structs, + // ``` + // struct Foo { + // the_foos: Vec + // } + // ``` + if !matches!( + span.ctxt().outer_expn_data().kind, + ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) + ) { + return false; + } + if snippet.starts_with('&') { + // This is already a literal borrow and the obligation is failing + // somewhere else in the obligation chain. Do not suggest non-sense. + return false; + } + // We have a very specific type of error, where just borrowing this argument + // might solve the problem. In cases like this, the important part is the + // original type obligation, not the last one that failed, which is arbitrary. + // Because of this, we modify the error to refer to the original obligation and + // return early in the caller. + + let msg = format!("the trait bound `{}` is not satisfied", old_pred); + if has_custom_message { + err.note(&msg); + } else { + err.message = + vec![(rustc_errors::DiagnosticMessage::Str(msg), Style::NoStyle)]; + } + err.span_label( + span, + format!( + "the trait `{}` is not implemented for `{}`", + old_pred.print_modifiers_and_trait_path(), + old_pred.self_ty().skip_binder(), + ), + ); + + if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred { + err.span_suggestions( + span.shrink_to_lo(), + "consider borrowing here", + ["&".to_string(), "&mut ".to_string()].into_iter(), + Applicability::MaybeIncorrect, + ); + } else { + let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut; + err.span_suggestion_verbose( + span.shrink_to_lo(), &format!( - "expected an implementor of trait `{}`", - old_pred.print_modifiers_and_trait_path(), + "consider{} borrowing here", + if is_mut { " mutably" } else { "" } ), + format!("&{}", if is_mut { "mut " } else { "" }), + Applicability::MaybeIncorrect, ); - - // This if is to prevent a special edge-case - if matches!( - span.ctxt().outer_expn_data().kind, - ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) - ) { - // We don't want a borrowing suggestion on the fields in structs, - // ``` - // struct Foo { - // the_foos: Vec - // } - // ``` - - if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred { - err.span_suggestions( - span.shrink_to_lo(), - "consider borrowing here", - ["&".to_string(), "&mut ".to_string()].into_iter(), - Applicability::MaybeIncorrect, - ); - } else { - let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut; - err.span_suggestion_verbose( - span.shrink_to_lo(), - &format!( - "consider{} borrowing here", - if is_mut { " mutably" } else { "" } - ), - format!("&{}", if is_mut { "mut " } else { "" }), - Applicability::MaybeIncorrect, - ); - } - } - return true; } + return true; } - return false; - }; + } + return false; + }; if let ObligationCauseCode::ImplDerivedObligation(cause) = &*code { try_borrowing(cause.derived.parent_trait_pred, &[]) } else if let ObligationCauseCode::BindingObligation(_, _) - | ObligationCauseCode::ItemObligation(..) = code + | ObligationCauseCode::ItemObligation(_) + | ObligationCauseCode::ExprItemObligation(..) + | ObligationCauseCode::ExprBindingObligation(..) = code { try_borrowing(poly_trait_pred, &never_suggest_borrow) } else { @@ -2244,11 +2267,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { region, object_ty, )); } - ObligationCauseCode::ItemObligation(_item_def_id) => { + ObligationCauseCode::ItemObligation(_) + | ObligationCauseCode::ExprItemObligation(..) => { // We hold the `DefId` of the item introducing the obligation, but displaying it // doesn't add user usable information. It always point at an associated item. } - ObligationCauseCode::BindingObligation(item_def_id, span) => { + ObligationCauseCode::BindingObligation(item_def_id, span) + | ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..) => { let item_name = tcx.def_path_str(item_def_id); let mut multispan = MultiSpan::from(span); if let Some(ident) = tcx.opt_item_ident(item_def_id) { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index b6d6df1eec6a1..85ff6e23711ca 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -117,11 +117,21 @@ pub enum TraitQueryMode { /// Creates predicate obligations from the generic bounds. pub fn predicates_for_generics<'tcx>( - cause: ObligationCause<'tcx>, + cause: impl Fn(usize, Span) -> ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, generic_bounds: ty::InstantiatedPredicates<'tcx>, ) -> impl Iterator> { - util::predicates_for_generics(cause, 0, param_env, generic_bounds) + let generic_bounds = generic_bounds; + debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds); + + std::iter::zip(generic_bounds.predicates, generic_bounds.spans).enumerate().map( + move |(idx, (predicate, span))| Obligation { + cause: cause(idx, span), + recursion_depth: 0, + param_env: param_env, + predicate, + }, + ) } /// Determines whether the type `ty` is known to meet `bound` and diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index d25006016629c..0f5dff01c6625 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -11,8 +11,6 @@ use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext}; pub use rustc_infer::traits::{self, util::*}; -use std::iter; - /////////////////////////////////////////////////////////////////////////// // `TraitAliasExpander` iterator /////////////////////////////////////////////////////////////////////////// @@ -210,7 +208,7 @@ pub fn impl_subject_and_oblig<'a, 'tcx>( let Normalized { value: predicates, obligations: normalization_obligations2 } = super::normalize(selcx, param_env, ObligationCause::dummy(), predicates); let impl_obligations = - predicates_for_generics(ObligationCause::dummy(), 0, param_env, predicates); + super::predicates_for_generics(|_, _| ObligationCause::dummy(), param_env, predicates); let impl_obligations = impl_obligations .chain(normalization_obligations1.into_iter()) @@ -219,27 +217,6 @@ pub fn impl_subject_and_oblig<'a, 'tcx>( (subject, impl_obligations) } -pub fn predicates_for_generics<'tcx>( - cause: ObligationCause<'tcx>, - recursion_depth: usize, - param_env: ty::ParamEnv<'tcx>, - generic_bounds: ty::InstantiatedPredicates<'tcx>, -) -> impl Iterator> { - debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds); - - iter::zip(generic_bounds.predicates, generic_bounds.spans).map(move |(predicate, span)| { - let cause = match *cause.code() { - traits::ItemObligation(def_id) if !span.is_dummy() => traits::ObligationCause::new( - cause.span, - cause.body_id, - traits::BindingObligation(def_id, span), - ), - _ => cause.clone(), - }; - Obligation { cause, recursion_depth, param_env, predicate } - }) -} - pub fn predicate_for_trait_ref<'tcx>( tcx: TyCtxt<'tcx>, cause: ObligationCause<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 7a5e67ff74b32..4bd179d239131 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -711,7 +711,7 @@ impl<'tcx> WfPredicates<'tcx> { iter::zip(iter::zip(predicates.predicates, predicates.spans), origins.into_iter().rev()) .map(|((mut pred, span), origin_def_id)| { let code = if span.is_dummy() { - traits::MiscObligation + traits::ItemObligation(origin_def_id) } else { traits::BindingObligation(origin_def_id, span) }; diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index cfc7c752a6bd6..32e6cb9c64f7f 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -7,6 +7,8 @@ result_into_ok_or_err )] #![allow(dead_code, unused_variables)] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] #[macro_use] extern crate tracing; diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index ec8d22e81d1c0..64846953aac75 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -1463,7 +1463,7 @@ pub fn check_type_bounds<'tcx>( ); let mk_cause = |span: Span| { let code = if span.is_dummy() { - traits::MiscObligation + traits::ItemObligation(trait_ty.def_id) } else { traits::BindingObligation(trait_ty.def_id, span) }; diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 1d9d04ceec0d7..20d25d508d224 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -607,9 +607,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[instrument(skip(self), level = "debug")] pub(in super::super) fn select_all_obligations_or_error(&self) { - let errors = self.fulfillment_cx.borrow_mut().select_all_or_error(&self); + let mut errors = self.fulfillment_cx.borrow_mut().select_all_or_error(&self); if !errors.is_empty() { + self.adjust_fulfillment_errors_for_expr_obligation(&mut errors); self.report_fulfillment_errors(&errors, self.inh.body_id, false); } } @@ -623,6 +624,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut result = self.fulfillment_cx.borrow_mut().select_where_possible(self); if !result.is_empty() { mutate_fulfillment_errors(&mut result); + self.adjust_fulfillment_errors_for_expr_obligation(&mut result); self.report_fulfillment_errors(&result, self.inh.body_id, fallback_has_occurred); } } @@ -820,23 +822,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = item_ty.subst(self.tcx, substs); self.write_resolution(hir_id, Ok((def_kind, def_id))); - self.add_required_obligations_with_code( - span, - def_id, - &substs, - match lang_item { - hir::LangItem::IntoFutureIntoFuture => { - ObligationCauseCode::AwaitableExpr(expr_hir_id) - } - hir::LangItem::IteratorNext | hir::LangItem::IntoIterIntoIter => { - ObligationCauseCode::ForLoopIterator - } - hir::LangItem::TryTraitFromOutput - | hir::LangItem::TryTraitFromResidual - | hir::LangItem::TryTraitBranch => ObligationCauseCode::QuestionMark, - _ => traits::ItemObligation(def_id), - }, - ); + + let code = match lang_item { + hir::LangItem::IntoFutureIntoFuture => { + Some(ObligationCauseCode::AwaitableExpr(expr_hir_id)) + } + hir::LangItem::IteratorNext | hir::LangItem::IntoIterIntoIter => { + Some(ObligationCauseCode::ForLoopIterator) + } + hir::LangItem::TryTraitFromOutput + | hir::LangItem::TryTraitFromResidual + | hir::LangItem::TryTraitBranch => Some(ObligationCauseCode::QuestionMark), + _ => None, + }; + if let Some(code) = code { + self.add_required_obligations_with_code(span, def_id, substs, move |_, _| code.clone()); + } else { + self.add_required_obligations_for_hir(span, def_id, substs, hir_id); + } + (Res::Def(def_kind, def_id), ty) } @@ -1348,7 +1352,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // First, store the "user substs" for later. self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty); - self.add_required_obligations(span, def_id, &substs); + self.add_required_obligations_for_hir(span, def_id, &substs, hir_id); // Substitute the values for the type parameters into the type of // the referenced item. @@ -1385,32 +1389,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Add all the obligations that are required, substituting and normalized appropriately. - pub(crate) fn add_required_obligations( + pub(crate) fn add_required_obligations_for_hir( &self, span: Span, def_id: DefId, - substs: &SubstsRef<'tcx>, + substs: SubstsRef<'tcx>, + hir_id: hir::HirId, ) { - self.add_required_obligations_with_code( - span, - def_id, - substs, - traits::ItemObligation(def_id), - ) + self.add_required_obligations_with_code(span, def_id, substs, |idx, span| { + if span.is_dummy() { + ObligationCauseCode::ExprItemObligation(def_id, hir_id, idx) + } else { + ObligationCauseCode::ExprBindingObligation(def_id, span, hir_id, idx) + } + }) } - #[tracing::instrument(level = "debug", skip(self, span, def_id, substs))] + #[tracing::instrument(level = "debug", skip(self, code, span, def_id, substs))] fn add_required_obligations_with_code( &self, span: Span, def_id: DefId, - substs: &SubstsRef<'tcx>, - code: ObligationCauseCode<'tcx>, + substs: SubstsRef<'tcx>, + code: impl Fn(usize, Span) -> ObligationCauseCode<'tcx>, ) { let (bounds, _) = self.instantiate_bounds(span, def_id, &substs); for obligation in traits::predicates_for_generics( - traits::ObligationCause::new(span, self.body_id, code), + |idx, predicate_span| { + traits::ObligationCause::new(span, self.body_id, code(idx, predicate_span)) + }, self.param_env, bounds, ) { diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index aab60de80ef14..3642b2ab03bfa 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -15,6 +15,7 @@ use crate::check::{ use crate::structured_errors::StructuredDiagnostic; use rustc_ast as ast; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::{pluralize, Applicability, Diagnostic, DiagnosticId, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; @@ -27,13 +28,14 @@ use rustc_infer::infer::InferOk; use rustc_infer::infer::TypeTrace; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::{self, DefIdTree, IsSuggestable, Ty}; +use rustc_middle::ty::{self, DefIdTree, IsSuggestable, Ty, TypeSuperVisitable, TypeVisitor}; use rustc_session::Session; use rustc_span::symbol::Ident; use rustc_span::{self, Span}; use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext}; use std::iter; +use std::ops::ControlFlow; use std::slice; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -247,17 +249,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Cause selection errors caused by resolving a single argument to point at the // argument and not the call. This lets us customize the span pointed to in the // fulfillment error to be more accurate. - let coerced_ty = - self.resolve_vars_with_obligations_and_mutate_fulfillment(coerced_ty, |errors| { - self.point_at_type_arg_instead_of_call_if_possible(errors, call_expr); - self.point_at_arg_instead_of_call_if_possible( - errors, - call_expr, - call_span, - provided_args, - &expected_input_tys, - ); - }); + let coerced_ty = self.resolve_vars_with_obligations(coerced_ty); let coerce_error = self .try_coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None) @@ -312,16 +304,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // an "opportunistic" trait resolution of any trait bounds on // the call. This helps coercions. if check_closures { - self.select_obligations_where_possible(false, |errors| { - self.point_at_type_arg_instead_of_call_if_possible(errors, call_expr); - self.point_at_arg_instead_of_call_if_possible( - errors, - call_expr, - call_span, - &provided_args, - &expected_input_tys, - ); - }) + self.select_obligations_where_possible(false, |_| {}) } // Check each argument, to satisfy the input it was provided for @@ -674,7 +657,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MachineApplicable, ); }; - self.label_fn_like(&mut err, fn_def_id, callee_ty, Some(mismatch_idx), is_method); + self.label_fn_like( + &mut err, + fn_def_id, + callee_ty, + Some(mismatch_idx), + is_method, + ); err.emit(); return; } @@ -1081,8 +1070,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let suggestion_text = if let Some(provided_idx) = provided_idx && let (_, provided_span) = provided_arg_tys[*provided_idx] - && let Ok(arg_text) = - source_map.span_to_snippet(provided_span) + && let Ok(arg_text) = source_map.span_to_snippet(provided_span) { arg_text } else { @@ -1183,7 +1171,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.write_user_type_annotation_from_substs(hir_id, did, substs, None); // Check bounds on type arguments used in the path. - self.add_required_obligations(path_span, did, substs); + self.add_required_obligations_for_hir(path_span, did, substs, hir_id); Some((variant, ty)) } else { @@ -1620,183 +1608,406 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk - /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s - /// reference a type argument. The reason to walk also the checked type is that the coerced type - /// can be not easily comparable with predicate type (because of coercion). If the types match - /// for either checked or coerced type, and there's only *one* argument that does, we point at - /// the corresponding argument's expression span instead of the `fn` call path span. - fn point_at_arg_instead_of_call_if_possible( + /// Given a vector of fulfillment errors, try to adjust the spans of the + /// errors to more accurately point at the cause of the failure. + /// + /// This applies to calls, methods, and struct expressions. This will also + /// try to deduplicate errors that are due to the same cause but might + /// have been created with different [`ObligationCause`][traits::ObligationCause]s. + pub(super) fn adjust_fulfillment_errors_for_expr_obligation( &self, errors: &mut Vec>, - expr: &'tcx hir::Expr<'tcx>, - call_sp: Span, - args: &'tcx [hir::Expr<'tcx>], - expected_tys: &[Ty<'tcx>], ) { - // We *do not* do this for desugared call spans to keep good diagnostics when involving - // the `?` operator. - if call_sp.desugaring_kind().is_some() { - return; + // Store a mapping from `(Span, Predicate) -> ObligationCause`, so that + // other errors that have the same span and predicate can also get fixed, + // even if their `ObligationCauseCode` isn't an `Expr*Obligation` kind. + // This is important since if we adjust one span but not the other, then + // we will have "duplicated" the error on the UI side. + let mut remap_cause = FxHashSet::default(); + let mut not_adjusted = vec![]; + + for error in errors { + let before_span = error.obligation.cause.span; + if self.adjust_fulfillment_error_for_expr_obligation(error) + || before_span != error.obligation.cause.span + { + // Store both the predicate and the predicate *without constness* + // since sometimes we instantiate and check both of these in a + // method call, for example. + remap_cause.insert(( + before_span, + error.obligation.predicate, + error.obligation.cause.clone(), + )); + remap_cause.insert(( + before_span, + error.obligation.predicate.without_const(self.tcx), + error.obligation.cause.clone(), + )); + } else { + // If it failed to be adjusted once around, it may be adjusted + // via the "remap cause" mapping the second time... + not_adjusted.push(error); + } } - 'outer: for error in errors { - // Only if the cause is somewhere inside the expression we want try to point at arg. - // Otherwise, it means that the cause is somewhere else and we should not change - // anything because we can break the correct span. - if !call_sp.contains(error.obligation.cause.span) { - continue; + for error in not_adjusted { + for (span, predicate, cause) in &remap_cause { + if *predicate == error.obligation.predicate + && span.contains(error.obligation.cause.span) + { + error.obligation.cause = cause.clone(); + continue; + } } + } + } - // Peel derived obligation, because it's the type that originally - // started this inference chain that matters, not the one we wound - // up with at the end. - fn unpeel_to_top<'a, 'tcx>( - mut code: &'a ObligationCauseCode<'tcx>, - ) -> &'a ObligationCauseCode<'tcx> { - let mut result_code = code; - loop { - let parent = match code { - ObligationCauseCode::ImplDerivedObligation(c) => &c.derived.parent_code, - ObligationCauseCode::BuiltinDerivedObligation(c) - | ObligationCauseCode::DerivedObligation(c) => &c.parent_code, - _ => break result_code, - }; - (result_code, code) = (code, parent); + fn adjust_fulfillment_error_for_expr_obligation( + &self, + error: &mut traits::FulfillmentError<'tcx>, + ) -> bool { + let (traits::ExprItemObligation(def_id, hir_id, idx) | traits::ExprBindingObligation(def_id, _, hir_id, idx)) + = *error.obligation.cause.code().peel_derives() else { return false; }; + let hir = self.tcx.hir(); + let hir::Node::Expr(expr) = hir.get(hir_id) else { return false; }; + + // Skip over mentioning async lang item + if Some(def_id) == self.tcx.lang_items().from_generator_fn() + && error.obligation.cause.span.desugaring_kind() + == Some(rustc_span::DesugaringKind::Async) + { + return false; + } + + let Some(unsubstituted_pred) = + self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).predicates.into_iter().nth(idx) + else { return false; }; + + let generics = self.tcx.generics_of(def_id); + let predicate_substs = match unsubstituted_pred.kind().skip_binder() { + ty::PredicateKind::Trait(pred) => pred.trait_ref.substs, + ty::PredicateKind::Projection(pred) => pred.projection_ty.substs, + _ => ty::List::empty(), + }; + + let find_param_matching = |matches: &dyn Fn(&ty::ParamTy) -> bool| { + predicate_substs.types().find_map(|ty| { + ty.walk().find_map(|arg| { + if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Param(param_ty) = ty.kind() + && matches(param_ty) + { + Some(arg) + } else { + None + } + }) + }) + }; + + // Prefer generics that are local to the fn item, since these are likely + // to be the cause of the unsatisfied predicate. + let mut param_to_point_at = find_param_matching(&|param_ty| { + self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) == def_id + }); + // Fall back to generic that isn't local to the fn item. This will come + // from a trait or impl, for example. + let mut fallback_param_to_point_at = find_param_matching(&|param_ty| { + self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) != def_id + && param_ty.name != rustc_span::symbol::kw::SelfUpper + }); + // Finally, the `Self` parameter is possibly the reason that the predicate + // is unsatisfied. This is less likely to be true for methods, because + // method probe means that we already kinda check that the predicates due + // to the `Self` type are true. + let mut self_param_to_point_at = + find_param_matching(&|param_ty| param_ty.name == rustc_span::symbol::kw::SelfUpper); + + // Finally, for ambiguity-related errors, we actually want to look + // for a parameter that is the source of the inference type left + // over in this predicate. + if let traits::FulfillmentErrorCode::CodeAmbiguity = error.code { + fallback_param_to_point_at = None; + self_param_to_point_at = None; + param_to_point_at = + self.find_ambiguous_parameter_in(def_id, error.root_obligation.predicate); + } + + if self.closure_span_overlaps_error(error, expr.span) { + return false; + } + + match &expr.kind { + hir::ExprKind::Path(qpath) => { + if let hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Call(callee, args), + hir_id: call_hir_id, + span: call_span, + .. + }) = hir.get(hir.get_parent_node(expr.hir_id)) + && callee.hir_id == expr.hir_id + { + if self.closure_span_overlaps_error(error, *call_span) { + return false; + } + + for param in + [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] + .into_iter() + .flatten() + { + if self.point_at_arg_if_possible( + error, + def_id, + param, + *call_hir_id, + callee.span, + args, + ) + { + return true; + } + } + // Notably, we only point to params that are local to the + // item we're checking, since those are the ones we are able + // to look in the final `hir::PathSegment` for. Everything else + // would require a deeper search into the `qpath` than I think + // is worthwhile. + if let Some(param_to_point_at) = param_to_point_at + && self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath) + { + return true; + } } } - let self_: ty::subst::GenericArg<'_> = - match unpeel_to_top(error.obligation.cause.code()) { - ObligationCauseCode::BuiltinDerivedObligation(code) - | ObligationCauseCode::DerivedObligation(code) => { - code.parent_trait_pred.self_ty().skip_binder().into() - } - ObligationCauseCode::ImplDerivedObligation(code) => { - code.derived.parent_trait_pred.self_ty().skip_binder().into() + hir::ExprKind::MethodCall(segment, args, ..) => { + for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] + .into_iter() + .flatten() + { + if self.point_at_arg_if_possible( + error, + def_id, + param, + hir_id, + segment.ident.span, + args, + ) { + return true; } - _ => match error.obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Trait(predicate) => predicate.self_ty().into(), - ty::PredicateKind::Projection(predicate) => { - predicate.projection_ty.self_ty().into() + } + if let Some(param_to_point_at) = param_to_point_at + && self.point_at_generic_if_possible(error, def_id, param_to_point_at, segment) + { + return true; + } + } + hir::ExprKind::Struct(qpath, fields, ..) => { + if let Res::Def(DefKind::Struct | DefKind::Variant, variant_def_id) = + self.typeck_results.borrow().qpath_res(qpath, hir_id) + { + for param in + [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] + { + if let Some(param) = param + && self.point_at_field_if_possible( + error, + def_id, + param, + variant_def_id, + fields, + ) + { + return true; } - _ => continue, - }, - }; - let self_ = self.resolve_vars_if_possible(self_); - let ty_matches_self = |ty: Ty<'tcx>| ty.walk().any(|arg| arg == self_); - - let typeck_results = self.typeck_results.borrow(); - - for (idx, arg) in args.iter().enumerate() { - // Don't adjust the span if we already have a more precise span - // within one of the args. - if arg.span.contains(error.obligation.cause.span) { - let references_arg = - typeck_results.expr_ty_opt(arg).map_or(false, &ty_matches_self) - || expected_tys.get(idx).copied().map_or(false, &ty_matches_self); - if references_arg && !arg.span.from_expansion() { - error.obligation.cause.map_code(|parent_code| { - ObligationCauseCode::FunctionArgumentObligation { - arg_hir_id: args[idx].hir_id, - call_hir_id: expr.hir_id, - parent_code, - } - }) } - continue 'outer; + } + if let Some(param_to_point_at) = param_to_point_at + && self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath) + { + return true; } } + _ => {} + } - // Collect the argument position for all arguments that could have caused this - // `FulfillmentError`. - let mut referenced_in: Vec<_> = std::iter::zip(expected_tys, args) - .enumerate() - .flat_map(|(idx, (expected_ty, arg))| { - if let Some(arg_ty) = typeck_results.expr_ty_opt(arg) { - vec![(idx, arg_ty), (idx, *expected_ty)] - } else { - vec![] - } - }) - .filter_map(|(i, ty)| { - let ty = self.resolve_vars_if_possible(ty); - // We walk the argument type because the argument's type could have - // been `Option`, but the `FulfillmentError` references `T`. - if ty_matches_self(ty) { Some(i) } else { None } - }) - .collect(); + false + } - // Both checked and coerced types could have matched, thus we need to remove - // duplicates. + fn closure_span_overlaps_error( + &self, + error: &traits::FulfillmentError<'tcx>, + span: Span, + ) -> bool { + if let traits::FulfillmentErrorCode::CodeSelectionError( + traits::SelectionError::OutputTypeParameterMismatch(_, expected, _), + ) = error.code + && let ty::Closure(def_id, _) | ty::Generator(def_id, ..) = expected.skip_binder().self_ty().kind() + && span.overlaps(self.tcx.def_span(*def_id)) + { + true + } else { + false + } + } - // We sort primitive type usize here and can use unstable sort - referenced_in.sort_unstable(); - referenced_in.dedup(); + fn point_at_arg_if_possible( + &self, + error: &mut traits::FulfillmentError<'tcx>, + def_id: DefId, + param_to_point_at: ty::GenericArg<'tcx>, + call_hir_id: hir::HirId, + callee_span: Span, + args: &[hir::Expr<'tcx>], + ) -> bool { + let sig = self.tcx.fn_sig(def_id).skip_binder(); + let args_referencing_param: Vec<_> = sig + .inputs() + .iter() + .enumerate() + .filter(|(_, ty)| find_param_in_ty(**ty, param_to_point_at)) + .collect(); - if let &[idx] = &referenced_in[..] { - // Do not point at the inside of a macro. - // That would often result in poor error messages. - if args[idx].span.from_expansion() { - continue; + // If there's one field that references the given generic, great! + if let [(idx, _)] = args_referencing_param.as_slice() && let Some(arg) = args.get(*idx) { + error.obligation.cause.span = arg.span.find_ancestor_in_same_ctxt(error.obligation.cause.span).unwrap_or(arg.span); + error.obligation.cause.map_code(|parent_code| { + ObligationCauseCode::FunctionArgumentObligation { + arg_hir_id: arg.hir_id, + call_hir_id, + parent_code, } - // We make sure that only *one* argument matches the obligation failure - // and we assign the obligation's span to its expression's. - error.obligation.cause.span = args[idx].span; - error.obligation.cause.map_code(|parent_code| { - ObligationCauseCode::FunctionArgumentObligation { - arg_hir_id: args[idx].hir_id, - call_hir_id: expr.hir_id, - parent_code, - } - }); - } else if error.obligation.cause.span == call_sp { - // Make function calls point at the callee, not the whole thing. - if let hir::ExprKind::Call(callee, _) = expr.kind { - error.obligation.cause.span = callee.span; + }); + return true; + } else if args_referencing_param.len() > 0 { + // If more than one argument applies, then point to the callee span at least... + // We have chance to fix this up further in `point_at_generics_if_possible` + error.obligation.cause.span = callee_span; + } + + false + } + + fn point_at_field_if_possible( + &self, + error: &mut traits::FulfillmentError<'tcx>, + def_id: DefId, + param_to_point_at: ty::GenericArg<'tcx>, + variant_def_id: DefId, + expr_fields: &[hir::ExprField<'tcx>], + ) -> bool { + let def = self.tcx.adt_def(def_id); + + let identity_substs = ty::InternalSubsts::identity_for_item(self.tcx, def_id); + let fields_referencing_param: Vec<_> = def + .variant_with_id(variant_def_id) + .fields + .iter() + .filter(|field| { + let field_ty = field.ty(self.tcx, identity_substs); + find_param_in_ty(field_ty, param_to_point_at) + }) + .collect(); + + if let [field] = fields_referencing_param.as_slice() { + for expr_field in expr_fields { + // Look for the ExprField that matches the field, using the + // same rules that check_expr_struct uses for macro hygiene. + if self.tcx.adjust_ident(expr_field.ident, variant_def_id) == field.ident(self.tcx) + { + error.obligation.cause.span = expr_field + .expr + .span + .find_ancestor_in_same_ctxt(error.obligation.cause.span) + .unwrap_or(expr_field.span); + return true; } } } + + false } - /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the - /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s - /// were caused by them. If they were, we point at the corresponding type argument's span - /// instead of the `fn` call path span. - fn point_at_type_arg_instead_of_call_if_possible( + fn point_at_path_if_possible( &self, - errors: &mut Vec>, - call_expr: &'tcx hir::Expr<'tcx>, - ) { - if let hir::ExprKind::Call(path, _) = &call_expr.kind { - if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = &path.kind { - for error in errors { - let self_ty = match error.obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Trait(predicate) => predicate.self_ty(), - ty::PredicateKind::Projection(predicate) => { - predicate.projection_ty.self_ty() - } - _ => continue, - }; - // If any of the type arguments in this path segment caused the - // `FulfillmentError`, point at its span (#61860). - for arg in path - .segments - .iter() - .filter_map(|seg| seg.args.as_ref()) - .flat_map(|a| a.args.iter()) - { - if let hir::GenericArg::Type(hir_ty) = &arg - && let Some(ty) = - self.typeck_results.borrow().node_type_opt(hir_ty.hir_id) - && self.resolve_vars_if_possible(ty) == self_ty - { - error.obligation.cause.span = hir_ty.span; - break; - } - } + error: &mut traits::FulfillmentError<'tcx>, + def_id: DefId, + param: ty::GenericArg<'tcx>, + qpath: &QPath<'tcx>, + ) -> bool { + match qpath { + hir::QPath::Resolved(_, path) => { + if let Some(segment) = path.segments.last() + && self.point_at_generic_if_possible(error, def_id, param, segment) + { + return true; + } + } + hir::QPath::TypeRelative(_, segment) => { + if self.point_at_generic_if_possible(error, def_id, param, segment) { + return true; + } + } + _ => {} + } + + false + } + + fn point_at_generic_if_possible( + &self, + error: &mut traits::FulfillmentError<'tcx>, + def_id: DefId, + param_to_point_at: ty::GenericArg<'tcx>, + segment: &hir::PathSegment<'tcx>, + ) -> bool { + let own_substs = self + .tcx + .generics_of(def_id) + .own_substs(ty::InternalSubsts::identity_for_item(self.tcx, def_id)); + let Some((index, _)) = own_substs + .iter() + .filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_))) + .enumerate() + .find(|(_, arg)| **arg == param_to_point_at) else { return false }; + let Some(arg) = segment + .args() + .args + .iter() + .filter(|arg| matches!(arg, hir::GenericArg::Type(_))) + .nth(index) else { return false; }; + error.obligation.cause.span = arg + .span() + .find_ancestor_in_same_ctxt(error.obligation.cause.span) + .unwrap_or(arg.span()); + true + } + + fn find_ambiguous_parameter_in>( + &self, + item_def_id: DefId, + t: T, + ) -> Option> { + struct FindAmbiguousParameter<'a, 'tcx>(&'a FnCtxt<'a, 'tcx>, DefId); + impl<'tcx> TypeVisitor<'tcx> for FindAmbiguousParameter<'_, 'tcx> { + type BreakTy = ty::GenericArg<'tcx>; + fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow { + if let Some(origin) = self.0.type_var_origin(ty) + && let TypeVariableOriginKind::TypeParameterDefinition(_, Some(def_id)) = + origin.kind + && let generics = self.0.tcx.generics_of(self.1) + && let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id) + && let Some(subst) = ty::InternalSubsts::identity_for_item(self.0.tcx, self.1) + .get(index as usize) + { + ControlFlow::Break(*subst) + } else { + ty.super_visit_with(self) } } } + t.visit_with(&mut FindAmbiguousParameter(self, item_def_id)).break_value() } fn label_fn_like( @@ -1864,14 +2075,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let new_def_id = self.probe(|_| { let trait_ref = ty::TraitRef::new( call_kind.to_def_id(self.tcx), - self.tcx.mk_substs([ - ty::GenericArg::from(callee_ty), - self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: rustc_span::DUMMY_SP, - }) - .into(), - ].into_iter()), + self.tcx.mk_substs( + [ + ty::GenericArg::from(callee_ty), + self.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::MiscVariable, + span: rustc_span::DUMMY_SP, + }) + .into(), + ] + .into_iter(), + ), ); let obligation = traits::Obligation::new( traits::ObligationCause::dummy(), @@ -1886,7 +2100,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(Some(traits::ImplSource::UserDefined(impl_source))) => { Some(impl_source.impl_def_id) } - _ => None + _ => None, } }); if let Some(new_def_id) = new_def_id { @@ -1940,3 +2154,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } + +fn find_param_in_ty<'tcx>(ty: Ty<'tcx>, param_to_point_at: ty::GenericArg<'tcx>) -> bool { + let mut walk = ty.walk(); + while let Some(arg) = walk.next() { + if arg == param_to_point_at { + return true; + } else if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Projection(..) = ty.kind() + { + // This logic may seem a bit strange, but typically when + // we have a projection type in a function signature, the + // argument that's being passed into that signature is + // not actually constraining that projection's substs in + // a meaningful way. So we skip it, and see improvements + // in some UI tests. + walk.skip_current_subtree(); + } + } + false +} diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index 2c89b63ae84f8..59fd5c315ae63 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -491,7 +491,19 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // so we just call `predicates_for_generics` directly to avoid redoing work. // `self.add_required_obligations(self.span, def_id, &all_substs);` for obligation in traits::predicates_for_generics( - traits::ObligationCause::new(self.span, self.body_id, traits::ItemObligation(def_id)), + |idx, span| { + let code = if span.is_dummy() { + ObligationCauseCode::ExprItemObligation(def_id, self.call_expr.hir_id, idx) + } else { + ObligationCauseCode::ExprBindingObligation( + def_id, + span, + self.call_expr.hir_id, + idx, + ) + }; + traits::ObligationCause::new(self.span, self.body_id, code) + }, self.param_env, method_predicates, ) { diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 0e678c41f8b40..de26a9e56e2d6 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -534,7 +534,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { traits::ObligationCause::misc(span, self.body_id) }; - obligations.extend(traits::predicates_for_generics(cause.clone(), self.param_env, bounds)); + let predicates_cause = cause.clone(); + obligations.extend(traits::predicates_for_generics( + move |_, _| predicates_cause.clone(), + self.param_env, + bounds, + )); // Also add an obligation for the method type being well-formed. let method_ty = tcx.mk_fn_ptr(ty::Binder::dummy(fn_sig)); diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index efe15fec7cbfa..d9870060a40bb 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -1514,8 +1514,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { traits::normalize(selcx, self.param_env, cause.clone(), impl_bounds); // Convert the bounds into obligations. - let impl_obligations = - traits::predicates_for_generics(cause, self.param_env, impl_bounds); + let impl_obligations = traits::predicates_for_generics( + move |_, _| cause.clone(), + self.param_env, + impl_bounds, + ); let candidate_obligations = impl_obligations .chain(norm_obligations.into_iter()) diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs index 8b1cb8d1c939a..2214fc2ced883 100644 --- a/compiler/rustc_typeck/src/errors.rs +++ b/compiler/rustc_typeck/src/errors.rs @@ -6,7 +6,7 @@ use rustc_session::{parse::ParseSess, SessionDiagnostic}; use rustc_span::{symbol::Ident, Span, Symbol}; #[derive(SessionDiagnostic)] -#[error(typeck::field_multiply_specified_in_initializer, code = "E0062")] +#[diag(typeck::field_multiply_specified_in_initializer, code = "E0062")] pub struct FieldMultiplySpecifiedInInitializer { #[primary_span] #[label] @@ -17,7 +17,7 @@ pub struct FieldMultiplySpecifiedInInitializer { } #[derive(SessionDiagnostic)] -#[error(typeck::unrecognized_atomic_operation, code = "E0092")] +#[diag(typeck::unrecognized_atomic_operation, code = "E0092")] pub struct UnrecognizedAtomicOperation<'a> { #[primary_span] #[label] @@ -26,7 +26,7 @@ pub struct UnrecognizedAtomicOperation<'a> { } #[derive(SessionDiagnostic)] -#[error(typeck::wrong_number_of_generic_arguments_to_intrinsic, code = "E0094")] +#[diag(typeck::wrong_number_of_generic_arguments_to_intrinsic, code = "E0094")] pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> { #[primary_span] #[label] @@ -37,7 +37,7 @@ pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> { } #[derive(SessionDiagnostic)] -#[error(typeck::unrecognized_intrinsic_function, code = "E0093")] +#[diag(typeck::unrecognized_intrinsic_function, code = "E0093")] pub struct UnrecognizedIntrinsicFunction { #[primary_span] #[label] @@ -46,7 +46,7 @@ pub struct UnrecognizedIntrinsicFunction { } #[derive(SessionDiagnostic)] -#[error(typeck::lifetimes_or_bounds_mismatch_on_trait, code = "E0195")] +#[diag(typeck::lifetimes_or_bounds_mismatch_on_trait, code = "E0195")] pub struct LifetimesOrBoundsMismatchOnTrait { #[primary_span] #[label] @@ -58,7 +58,7 @@ pub struct LifetimesOrBoundsMismatchOnTrait { } #[derive(SessionDiagnostic)] -#[error(typeck::drop_impl_on_wrong_item, code = "E0120")] +#[diag(typeck::drop_impl_on_wrong_item, code = "E0120")] pub struct DropImplOnWrongItem { #[primary_span] #[label] @@ -66,7 +66,7 @@ pub struct DropImplOnWrongItem { } #[derive(SessionDiagnostic)] -#[error(typeck::field_already_declared, code = "E0124")] +#[diag(typeck::field_already_declared, code = "E0124")] pub struct FieldAlreadyDeclared { pub field_name: Ident, #[primary_span] @@ -77,7 +77,7 @@ pub struct FieldAlreadyDeclared { } #[derive(SessionDiagnostic)] -#[error(typeck::copy_impl_on_type_with_dtor, code = "E0184")] +#[diag(typeck::copy_impl_on_type_with_dtor, code = "E0184")] pub struct CopyImplOnTypeWithDtor { #[primary_span] #[label] @@ -85,14 +85,14 @@ pub struct CopyImplOnTypeWithDtor { } #[derive(SessionDiagnostic)] -#[error(typeck::multiple_relaxed_default_bounds, code = "E0203")] +#[diag(typeck::multiple_relaxed_default_bounds, code = "E0203")] pub struct MultipleRelaxedDefaultBounds { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(typeck::copy_impl_on_non_adt, code = "E0206")] +#[diag(typeck::copy_impl_on_non_adt, code = "E0206")] pub struct CopyImplOnNonAdt { #[primary_span] #[label] @@ -100,7 +100,7 @@ pub struct CopyImplOnNonAdt { } #[derive(SessionDiagnostic)] -#[error(typeck::trait_object_declared_with_no_traits, code = "E0224")] +#[diag(typeck::trait_object_declared_with_no_traits, code = "E0224")] pub struct TraitObjectDeclaredWithNoTraits { #[primary_span] pub span: Span, @@ -109,14 +109,14 @@ pub struct TraitObjectDeclaredWithNoTraits { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0227")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0227")] pub struct AmbiguousLifetimeBound { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(typeck::assoc_type_binding_not_allowed, code = "E0229")] +#[diag(typeck::assoc_type_binding_not_allowed, code = "E0229")] pub struct AssocTypeBindingNotAllowed { #[primary_span] #[label] @@ -124,14 +124,14 @@ pub struct AssocTypeBindingNotAllowed { } #[derive(SessionDiagnostic)] -#[error(typeck::functional_record_update_on_non_struct, code = "E0436")] +#[diag(typeck::functional_record_update_on_non_struct, code = "E0436")] pub struct FunctionalRecordUpdateOnNonStruct { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(typeck::typeof_reserved_keyword_used, code = "E0516")] +#[diag(typeck::typeof_reserved_keyword_used, code = "E0516")] pub struct TypeofReservedKeywordUsed<'tcx> { pub ty: Ty<'tcx>, #[primary_span] @@ -142,7 +142,7 @@ pub struct TypeofReservedKeywordUsed<'tcx> { } #[derive(SessionDiagnostic)] -#[error(typeck::return_stmt_outside_of_fn_body, code = "E0572")] +#[diag(typeck::return_stmt_outside_of_fn_body, code = "E0572")] pub struct ReturnStmtOutsideOfFnBody { #[primary_span] pub span: Span, @@ -153,14 +153,14 @@ pub struct ReturnStmtOutsideOfFnBody { } #[derive(SessionDiagnostic)] -#[error(typeck::yield_expr_outside_of_generator, code = "E0627")] +#[diag(typeck::yield_expr_outside_of_generator, code = "E0627")] pub struct YieldExprOutsideOfGenerator { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(typeck::struct_expr_non_exhaustive, code = "E0639")] +#[diag(typeck::struct_expr_non_exhaustive, code = "E0639")] pub struct StructExprNonExhaustive { #[primary_span] pub span: Span, @@ -168,14 +168,14 @@ pub struct StructExprNonExhaustive { } #[derive(SessionDiagnostic)] -#[error(typeck::method_call_on_unknown_type, code = "E0699")] +#[diag(typeck::method_call_on_unknown_type, code = "E0699")] pub struct MethodCallOnUnknownType { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(typeck::value_of_associated_struct_already_specified, code = "E0719")] +#[diag(typeck::value_of_associated_struct_already_specified, code = "E0719")] pub struct ValueOfAssociatedStructAlreadySpecified { #[primary_span] #[label] @@ -187,7 +187,7 @@ pub struct ValueOfAssociatedStructAlreadySpecified { } #[derive(SessionDiagnostic)] -#[error(typeck::address_of_temporary_taken, code = "E0745")] +#[diag(typeck::address_of_temporary_taken, code = "E0745")] pub struct AddressOfTemporaryTaken { #[primary_span] #[label] @@ -233,7 +233,7 @@ pub enum ExpectedReturnTypeLabel<'tcx> { } #[derive(SessionDiagnostic)] -#[error(typeck::unconstrained_opaque_type)] +#[diag(typeck::unconstrained_opaque_type)] #[note] pub struct UnconstrainedOpaqueType { #[primary_span] @@ -309,7 +309,7 @@ impl<'a> SessionDiagnostic<'a> for MissingTypeParams { } #[derive(SessionDiagnostic)] -#[error(typeck::manual_implementation, code = "E0183")] +#[diag(typeck::manual_implementation, code = "E0183")] #[help] pub struct ManualImplementation { #[primary_span] @@ -319,21 +319,21 @@ pub struct ManualImplementation { } #[derive(SessionDiagnostic)] -#[error(typeck::substs_on_overridden_impl)] +#[diag(typeck::substs_on_overridden_impl)] pub struct SubstsOnOverriddenImpl { #[primary_span] pub span: Span, } #[derive(LintDiagnostic)] -#[lint(typeck::unused_extern_crate)] +#[diag(typeck::unused_extern_crate)] pub struct UnusedExternCrate { #[suggestion(applicability = "machine-applicable", code = "")] pub span: Span, } #[derive(LintDiagnostic)] -#[lint(typeck::extern_crate_not_idiomatic)] +#[diag(typeck::extern_crate_not_idiomatic)] pub struct ExternCrateNotIdiomatic { #[suggestion_short(applicability = "machine-applicable", code = "{suggestion_code}")] pub span: Span, @@ -342,7 +342,7 @@ pub struct ExternCrateNotIdiomatic { } #[derive(SessionDiagnostic)] -#[error(typeck::expected_used_symbol)] +#[diag(typeck::expected_used_symbol)] pub struct ExpectedUsedSymbol { #[primary_span] pub span: Span, diff --git a/library/alloc/src/alloc/tests.rs b/library/alloc/src/alloc/tests.rs index 7d560964d85be..b2f0194599b28 100644 --- a/library/alloc/src/alloc/tests.rs +++ b/library/alloc/src/alloc/tests.rs @@ -15,7 +15,7 @@ fn allocate_zeroed() { let end = i.add(layout.size()); while i < end { assert_eq!(*i, 0); - i = i.offset(1); + i = i.add(1); } Global.deallocate(ptr.as_non_null_ptr(), layout); } diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 4d895d83745b2..57ab74e01590b 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2447,8 +2447,8 @@ impl VecDeque { let mut right_offset = 0; for i in left_edge..right_edge { right_offset = (i - left_edge) % (cap - right_edge); - let src: isize = (right_edge + right_offset) as isize; - ptr::swap(buf.add(i), buf.offset(src)); + let src = right_edge + right_offset; + ptr::swap(buf.add(i), buf.add(src)); } let n_ops = right_edge - left_edge; left_edge += n_ops; diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index ae61b1f1e8ed5..be21d8c722d78 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -436,9 +436,9 @@ impl CString { /// /// unsafe { /// assert_eq!(b'f', *ptr as u8); - /// assert_eq!(b'o', *ptr.offset(1) as u8); - /// assert_eq!(b'o', *ptr.offset(2) as u8); - /// assert_eq!(b'\0', *ptr.offset(3) as u8); + /// assert_eq!(b'o', *ptr.add(1) as u8); + /// assert_eq!(b'o', *ptr.add(2) as u8); + /// assert_eq!(b'\0', *ptr.add(3) as u8); /// /// // retake pointer to free memory /// let _ = CString::from_raw(ptr); diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 63d4d94529008..5733124ec7565 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -1024,7 +1024,7 @@ where // Consume the greater side. // If equal, prefer the right run to maintain stability. unsafe { - let to_copy = if is_less(&*right.offset(-1), &*left.offset(-1)) { + let to_copy = if is_less(&*right.sub(1), &*left.sub(1)) { decrement_and_get(left) } else { decrement_and_get(right) @@ -1038,12 +1038,12 @@ where unsafe fn get_and_increment(ptr: &mut *mut T) -> *mut T { let old = *ptr; - *ptr = unsafe { ptr.offset(1) }; + *ptr = unsafe { ptr.add(1) }; old } unsafe fn decrement_and_get(ptr: &mut *mut T) -> *mut T { - *ptr = unsafe { ptr.offset(-1) }; + *ptr = unsafe { ptr.sub(1) }; *ptr } diff --git a/library/alloc/src/vec/in_place_collect.rs b/library/alloc/src/vec/in_place_collect.rs index 55dcb84ad16f9..b211421b20270 100644 --- a/library/alloc/src/vec/in_place_collect.rs +++ b/library/alloc/src/vec/in_place_collect.rs @@ -267,7 +267,7 @@ where // one slot in the underlying storage will have been freed up and we can immediately // write back the result. unsafe { - let dst = dst_buf.offset(i as isize); + let dst = dst_buf.add(i); debug_assert!(dst as *const _ <= end, "InPlaceIterable contract violation"); ptr::write(dst, self.__iterator_get_unchecked(i)); // Since this executes user code which can panic we have to bump the pointer diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 1b483e3fc7793..e02ad391a595f 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -160,7 +160,7 @@ impl Iterator for IntoIter { Some(unsafe { mem::zeroed() }) } else { let old = self.ptr; - self.ptr = unsafe { self.ptr.offset(1) }; + self.ptr = unsafe { self.ptr.add(1) }; Some(unsafe { ptr::read(old) }) } @@ -272,7 +272,7 @@ impl DoubleEndedIterator for IntoIter { // Make up a value of this ZST. Some(unsafe { mem::zeroed() }) } else { - self.end = unsafe { self.end.offset(-1) }; + self.end = unsafe { self.end.sub(1) }; Some(unsafe { ptr::read(self.end) }) } @@ -288,7 +288,7 @@ impl DoubleEndedIterator for IntoIter { } } else { // SAFETY: same as for advance_by() - self.end = unsafe { self.end.offset(step_size.wrapping_neg() as isize) }; + self.end = unsafe { self.end.sub(step_size) }; } let to_drop = ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size); // SAFETY: same as for advance_by() diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index fa9f2131c0c1d..cea943602f770 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -542,8 +542,8 @@ impl Vec { /// /// unsafe { /// // Overwrite memory with 4, 5, 6 - /// for i in 0..len as isize { - /// ptr::write(p.offset(i), 4 + i); + /// for i in 0..len { + /// ptr::write(p.add(i), 4 + i); /// } /// /// // Put everything back together into a Vec @@ -702,8 +702,8 @@ impl Vec { /// /// unsafe { /// // Overwrite memory with 4, 5, 6 - /// for i in 0..len as isize { - /// ptr::write(p.offset(i), 4 + i); + /// for i in 0..len { + /// ptr::write(p.add(i), 4 + i); /// } /// /// // Put everything back together into a Vec @@ -1393,7 +1393,7 @@ impl Vec { if index < len { // Shift everything over to make space. (Duplicating the // `index`th element into two consecutive places.) - ptr::copy(p, p.offset(1), len - index); + ptr::copy(p, p.add(1), len - index); } else if index == len { // No elements need shifting. } else { @@ -1455,7 +1455,7 @@ impl Vec { ret = ptr::read(ptr); // Shift everything down to fill in that spot. - ptr::copy(ptr.offset(1), ptr, len - index - 1); + ptr::copy(ptr.add(1), ptr, len - index - 1); } self.set_len(len - 1); ret @@ -2408,7 +2408,7 @@ impl Vec { // Write all elements except the last one for _ in 1..n { ptr::write(ptr, value.next()); - ptr = ptr.offset(1); + ptr = ptr.add(1); // Increment the length in every step in case next() panics local_len.increment_len(1); } diff --git a/library/alloc/src/vec/spec_extend.rs b/library/alloc/src/vec/spec_extend.rs index 506ee0ecfa279..1ea9c827afd70 100644 --- a/library/alloc/src/vec/spec_extend.rs +++ b/library/alloc/src/vec/spec_extend.rs @@ -39,7 +39,7 @@ where let mut local_len = SetLenOnDrop::new(&mut self.len); iterator.for_each(move |element| { ptr::write(ptr, element); - ptr = ptr.offset(1); + ptr = ptr.add(1); // Since the loop executes user code which can panic we have to bump the pointer // after each step. // NB can't overflow since we would have had to alloc the address space diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs index 7379569dd68fe..e30329aa1cb6c 100644 --- a/library/alloc/tests/str.rs +++ b/library/alloc/tests/str.rs @@ -1010,11 +1010,11 @@ fn test_as_bytes_fail() { fn test_as_ptr() { let buf = "hello".as_ptr(); unsafe { - assert_eq!(*buf.offset(0), b'h'); - assert_eq!(*buf.offset(1), b'e'); - assert_eq!(*buf.offset(2), b'l'); - assert_eq!(*buf.offset(3), b'l'); - assert_eq!(*buf.offset(4), b'o'); + assert_eq!(*buf.add(0), b'h'); + assert_eq!(*buf.add(1), b'e'); + assert_eq!(*buf.add(2), b'l'); + assert_eq!(*buf.add(3), b'l'); + assert_eq!(*buf.add(4), b'o'); } } diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 15467e0191dbf..3d7b875eac15d 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2209,9 +2209,9 @@ pub(crate) fn is_nonoverlapping(src: *const T, dst: *const T, count: usize) - /// dst.reserve(src_len); /// /// unsafe { -/// // The call to offset is always safe because `Vec` will never +/// // The call to add is always safe because `Vec` will never /// // allocate more than `isize::MAX` bytes. -/// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize); +/// let dst_ptr = dst.as_mut_ptr().add(dst_len); /// let src_ptr = src.as_ptr(); /// /// // Truncate `src` without dropping its contents. We do this first, diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 23c46f1a74a31..efa434f239266 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1282,15 +1282,14 @@ impl f32 { #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "clamp", since = "1.50.0")] #[inline] - pub fn clamp(self, min: f32, max: f32) -> f32 { + pub fn clamp(mut self, min: f32, max: f32) -> f32 { assert!(min <= max); - let mut x = self; - if x < min { - x = min; + if self < min { + self = min; } - if x > max { - x = max; + if self > max { + self = max; } - x + self } } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index b5c8241d2943d..9e4334fe01ad8 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1280,15 +1280,14 @@ impl f64 { #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "clamp", since = "1.50.0")] #[inline] - pub fn clamp(self, min: f64, max: f64) -> f64 { + pub fn clamp(mut self, min: f64, max: f64) -> f64 { assert!(min <= max); - let mut x = self; - if x < min { - x = min; + if self < min { + self = min; } - if x > max { - x = max; + if self > max { + self = max; } - x + self } } diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index e79d47c9f98cd..ea6a70c2f4e74 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -674,8 +674,9 @@ impl [T] { /// assert!(v == [3, 2, 1]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_reverse", issue = "100784")] #[inline] - pub fn reverse(&mut self) { + pub const fn reverse(&mut self) { let half_len = self.len() / 2; let Range { start, end } = self.as_mut_ptr_range(); @@ -698,9 +699,9 @@ impl [T] { revswap(front_half, back_half, half_len); #[inline] - fn revswap(a: &mut [T], b: &mut [T], n: usize) { - debug_assert_eq!(a.len(), n); - debug_assert_eq!(b.len(), n); + const fn revswap(a: &mut [T], b: &mut [T], n: usize) { + debug_assert!(a.len() == n); + debug_assert!(b.len() == n); // Because this function is first compiled in isolation, // this check tells LLVM that the indexing below is @@ -708,8 +709,10 @@ impl [T] { // lengths of the slices are known -- it's removed. let (a, b) = (&mut a[..n], &mut b[..n]); - for i in 0..n { + let mut i = 0; + while i < n { mem::swap(&mut a[i], &mut b[n - 1 - i]); + i += 1; } } } @@ -2921,7 +2924,7 @@ impl [T] { let prev_ptr_write = ptr.add(next_write - 1); if !same_bucket(&mut *ptr_read, &mut *prev_ptr_write) { if next_read != next_write { - let ptr_write = prev_ptr_write.offset(1); + let ptr_write = prev_ptr_write.add(1); mem::swap(&mut *ptr_read, &mut *ptr_write); } next_write += 1; diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs index 6a201834b8e68..8b025da2a46ed 100644 --- a/library/core/src/slice/sort.rs +++ b/library/core/src/slice/sort.rs @@ -326,8 +326,8 @@ where unsafe { // Branchless comparison. *end_l = i as u8; - end_l = end_l.offset(!is_less(&*elem, pivot) as isize); - elem = elem.offset(1); + end_l = end_l.add(!is_less(&*elem, pivot) as usize); + elem = elem.add(1); } } } @@ -352,9 +352,9 @@ where // Plus, `block_r` was asserted to be less than `BLOCK` and `elem` will therefore at most be pointing to the beginning of the slice. unsafe { // Branchless comparison. - elem = elem.offset(-1); + elem = elem.sub(1); *end_r = i as u8; - end_r = end_r.offset(is_less(&*elem, pivot) as isize); + end_r = end_r.add(is_less(&*elem, pivot) as usize); } } } @@ -365,12 +365,12 @@ where if count > 0 { macro_rules! left { () => { - l.offset(*start_l as isize) + l.add(*start_l as usize) }; } macro_rules! right { () => { - r.offset(-(*start_r as isize) - 1) + r.sub((*start_r as usize) + 1) }; } @@ -398,16 +398,16 @@ where ptr::copy_nonoverlapping(right!(), left!(), 1); for _ in 1..count { - start_l = start_l.offset(1); + start_l = start_l.add(1); ptr::copy_nonoverlapping(left!(), right!(), 1); - start_r = start_r.offset(1); + start_r = start_r.add(1); ptr::copy_nonoverlapping(right!(), left!(), 1); } ptr::copy_nonoverlapping(&tmp, right!(), 1); mem::forget(tmp); - start_l = start_l.offset(1); - start_r = start_r.offset(1); + start_l = start_l.add(1); + start_r = start_r.add(1); } } @@ -420,7 +420,7 @@ where // safe. Otherwise, the debug assertions in the `is_done` case guarantee that // `width(l, r) == block_l + block_r`, namely, that the block sizes have been adjusted to account // for the smaller number of remaining elements. - l = unsafe { l.offset(block_l as isize) }; + l = unsafe { l.add(block_l) }; } if start_r == end_r { @@ -428,7 +428,7 @@ where // SAFETY: Same argument as [block-width-guarantee]. Either this is a full block `2*BLOCK`-wide, // or `block_r` has been adjusted for the last handful of elements. - r = unsafe { r.offset(-(block_r as isize)) }; + r = unsafe { r.sub(block_r) }; } if is_done { @@ -457,9 +457,9 @@ where // - `offsets_l` contains valid offsets into `v` collected during the partitioning of // the last block, so the `l.offset` calls are valid. unsafe { - end_l = end_l.offset(-1); - ptr::swap(l.offset(*end_l as isize), r.offset(-1)); - r = r.offset(-1); + end_l = end_l.sub(1); + ptr::swap(l.add(*end_l as usize), r.sub(1)); + r = r.sub(1); } } width(v.as_mut_ptr(), r) @@ -470,9 +470,9 @@ where while start_r < end_r { // SAFETY: See the reasoning in [remaining-elements-safety]. unsafe { - end_r = end_r.offset(-1); - ptr::swap(l, r.offset(-(*end_r as isize) - 1)); - l = l.offset(1); + end_r = end_r.sub(1); + ptr::swap(l, r.sub((*end_r as usize) + 1)); + l = l.add(1); } } width(v.as_mut_ptr(), l) diff --git a/library/core/src/str/validations.rs b/library/core/src/str/validations.rs index 04bc665233e38..2acef432f2063 100644 --- a/library/core/src/str/validations.rs +++ b/library/core/src/str/validations.rs @@ -216,12 +216,12 @@ pub(super) const fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { // SAFETY: since `align - index` and `ascii_block_size` are // multiples of `usize_bytes`, `block = ptr.add(index)` is // always aligned with a `usize` so it's safe to dereference - // both `block` and `block.offset(1)`. + // both `block` and `block.add(1)`. unsafe { let block = ptr.add(index) as *const usize; // break if there is a nonascii byte let zu = contains_nonascii(*block); - let zv = contains_nonascii(*block.offset(1)); + let zv = contains_nonascii(*block.add(1)); if zu || zv { break; } diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 40ca9abd6bdc9..3c96290fc537e 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -1554,8 +1554,8 @@ impl AtomicPtr { /// Offsets the pointer's address by adding `val` *bytes*, returning the /// previous pointer. /// - /// This is equivalent to using [`wrapping_add`] and [`cast`] to atomically - /// perform `ptr = ptr.cast::().wrapping_add(val).cast::()`. + /// This is equivalent to using [`wrapping_byte_add`] to atomically + /// perform `ptr = ptr.wrapping_byte_add(val)`. /// /// `fetch_byte_add` takes an [`Ordering`] argument which describes the /// memory ordering of this operation. All ordering modes are possible. Note @@ -1565,8 +1565,7 @@ impl AtomicPtr { /// **Note**: This method is only available on platforms that support atomic /// operations on [`AtomicPtr`]. /// - /// [`wrapping_add`]: pointer::wrapping_add - /// [`cast`]: pointer::cast + /// [`wrapping_byte_add`]: pointer::wrapping_byte_add /// /// # Examples /// @@ -1591,8 +1590,8 @@ impl AtomicPtr { /// Offsets the pointer's address by subtracting `val` *bytes*, returning the /// previous pointer. /// - /// This is equivalent to using [`wrapping_sub`] and [`cast`] to atomically - /// perform `ptr = ptr.cast::().wrapping_sub(val).cast::()`. + /// This is equivalent to using [`wrapping_byte_sub`] to atomically + /// perform `ptr = ptr.wrapping_byte_sub(val)`. /// /// `fetch_byte_sub` takes an [`Ordering`] argument which describes the /// memory ordering of this operation. All ordering modes are possible. Note @@ -1602,8 +1601,7 @@ impl AtomicPtr { /// **Note**: This method is only available on platforms that support atomic /// operations on [`AtomicPtr`]. /// - /// [`wrapping_sub`]: pointer::wrapping_sub - /// [`cast`]: pointer::cast + /// [`wrapping_byte_sub`]: pointer::wrapping_byte_sub /// /// # Examples /// diff --git a/library/panic_abort/src/android.rs b/library/panic_abort/src/android.rs index 18bb932f10ea9..0fd824f8a458d 100644 --- a/library/panic_abort/src/android.rs +++ b/library/panic_abort/src/android.rs @@ -42,7 +42,7 @@ pub(crate) unsafe fn android_set_abort_message(payload: *mut &mut dyn BoxMeUp) { return; // allocation failure } copy_nonoverlapping(msg.as_ptr(), buf as *mut u8, msg.len()); - buf.offset(msg.len() as isize).write(0); + buf.add(msg.len()).write(0); let func = transmute::(func_addr); func(buf); diff --git a/library/panic_unwind/src/dwarf/eh.rs b/library/panic_unwind/src/dwarf/eh.rs index 7394feab82f22..9aa966b5063b1 100644 --- a/library/panic_unwind/src/dwarf/eh.rs +++ b/library/panic_unwind/src/dwarf/eh.rs @@ -75,7 +75,7 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result let call_site_encoding = reader.read::(); let call_site_table_length = reader.read_uleb128(); - let action_table = reader.ptr.offset(call_site_table_length as isize); + let action_table = reader.ptr.add(call_site_table_length as usize); let ip = context.ip; if !USING_SJLJ_EXCEPTIONS { diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index 9aeae4b2cae69..bb313c7597b6c 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -329,7 +329,7 @@ impl SocketAddr { crate::ptr::copy_nonoverlapping( namespace.as_ptr(), - addr.sun_path.as_mut_ptr().offset(1) as *mut u8, + addr.sun_path.as_mut_ptr().add(1) as *mut u8, namespace.len(), ); let len = (sun_path_offset(&addr) + 1 + namespace.len()) as libc::socklen_t; diff --git a/library/std/src/process.rs b/library/std/src/process.rs index d6cba7e7598f6..d91d4fa64caa5 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -169,15 +169,15 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; pub struct Child { pub(crate) handle: imp::Process, - /// The handle for writing to the child's standard input (stdin), if it has - /// been captured. To avoid partially moving - /// the `child` and thus blocking yourself from calling - /// functions on `child` while using `stdin`, - /// you might find it helpful: + /// The handle for writing to the child's standard input (stdin), if it + /// has been captured. You might find it helpful to do /// /// ```compile_fail,E0425 /// let stdin = child.stdin.take().unwrap(); /// ``` + /// + /// to avoid partially moving the `child` and thus blocking yourself from calling + /// functions on `child` while using `stdin`. #[stable(feature = "process", since = "1.0.0")] pub stdin: Option, diff --git a/library/std/src/sys/sgx/abi/usercalls/tests.rs b/library/std/src/sys/sgx/abi/usercalls/tests.rs index 4320f0bccd199..58b8eb215d73c 100644 --- a/library/std/src/sys/sgx/abi/usercalls/tests.rs +++ b/library/std/src/sys/sgx/abi/usercalls/tests.rs @@ -17,12 +17,12 @@ fn test_copy_to_userspace_function() { dst.copy_from_enclave(&[0u8; 100]); // Copy src[0..size] to dst + offset - unsafe { copy_to_userspace(src.as_ptr(), dst.as_mut_ptr().offset(offset), size) }; + unsafe { copy_to_userspace(src.as_ptr(), dst.as_mut_ptr().add(offset), size) }; // Verify copy for byte in 0..size { unsafe { - assert_eq!(*dst.as_ptr().offset(offset + byte as isize), src[byte as usize]); + assert_eq!(*dst.as_ptr().add(offset + byte), src[byte as usize]); } } } diff --git a/library/std/src/sys/windows/alloc.rs b/library/std/src/sys/windows/alloc.rs index fdc81cdea7dec..fe00c08aa6a9a 100644 --- a/library/std/src/sys/windows/alloc.rs +++ b/library/std/src/sys/windows/alloc.rs @@ -168,7 +168,7 @@ unsafe fn allocate(layout: Layout, zeroed: bool) -> *mut u8 { // SAFETY: Because the size and alignment of a header is <= `MIN_ALIGN` and `aligned` // is aligned to at least `MIN_ALIGN` and has at least `MIN_ALIGN` bytes of padding before // it, it is safe to write a header directly before it. - unsafe { ptr::write((aligned as *mut Header).offset(-1), Header(ptr)) }; + unsafe { ptr::write((aligned as *mut Header).sub(1), Header(ptr)) }; // SAFETY: The returned pointer does not point to the to the start of an allocated block, // but there is a header readable directly before it containing the location of the start @@ -213,7 +213,7 @@ unsafe impl GlobalAlloc for System { // SAFETY: Because of the contract of `System`, `ptr` is guaranteed to be non-null // and have a header readable directly before it. - unsafe { ptr::read((ptr as *mut Header).offset(-1)).0 } + unsafe { ptr::read((ptr as *mut Header).sub(1)).0 } } }; diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index aed082b3e0abf..1361b9c90c021 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -512,7 +512,7 @@ impl File { )); } }; - let subst_ptr = path_buffer.offset(subst_off as isize); + let subst_ptr = path_buffer.add(subst_off.into()); let mut subst = slice::from_raw_parts(subst_ptr, subst_len as usize); // Absolute paths start with an NT internal namespace prefix `\??\` // We should not let it leak through. @@ -1345,10 +1345,10 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> { let v = br"\??\"; let v = v.iter().map(|x| *x as u16); for c in v.chain(original.as_os_str().encode_wide()) { - *buf.offset(i) = c; + *buf.add(i) = c; i += 1; } - *buf.offset(i) = 0; + *buf.add(i) = 0; i += 1; (*db).ReparseTag = c::IO_REPARSE_TAG_MOUNT_POINT; (*db).ReparseTargetMaximumLength = (i * 2) as c::WORD; diff --git a/library/std/src/sys/windows/os.rs b/library/std/src/sys/windows/os.rs index bcac996c024ec..352337ba32237 100644 --- a/library/std/src/sys/windows/os.rs +++ b/library/std/src/sys/windows/os.rs @@ -99,11 +99,11 @@ impl Iterator for Env { } let p = self.cur as *const u16; let mut len = 0; - while *p.offset(len) != 0 { + while *p.add(len) != 0 { len += 1; } - let s = slice::from_raw_parts(p, len as usize); - self.cur = self.cur.offset(len + 1); + let s = slice::from_raw_parts(p, len); + self.cur = self.cur.add(len + 1); // Windows allows environment variables to start with an equals // symbol (in any other position, this is the separator between diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 40a3cc6d12cac..bd5790d2ea882 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -25,10 +25,11 @@ use std::time::Instant; fn main() { let args = env::args_os().skip(1).collect::>(); + let arg = |name| args.windows(2).find(|args| args[0] == name).and_then(|args| args[1].to_str()); // Detect whether or not we're a build script depending on whether --target // is passed (a bit janky...) - let target = args.windows(2).find(|w| &*w[0] == "--target").and_then(|w| w[1].to_str()); + let target = arg("--target"); let version = args.iter().find(|w| &**w == "-vV"); let verbose = match env::var("RUSTC_VERBOSE") { @@ -59,8 +60,7 @@ fn main() { cmd.args(&args).env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); // Get the name of the crate we're compiling, if any. - let crate_name = - args.windows(2).find(|args| args[0] == "--crate-name").and_then(|args| args[1].to_str()); + let crate_name = arg("--crate-name"); if let Some(crate_name) = crate_name { if let Some(target) = env::var_os("RUSTC_TIME") { @@ -106,6 +106,15 @@ fn main() { { cmd.arg("-C").arg("panic=abort"); } + + // `-Ztls-model=initial-exec` must not be applied to proc-macros, see + // issue https://github.com/rust-lang/rust/issues/100530 + if env::var("RUSTC_TLS_MODEL_INITIAL_EXEC").is_ok() + && arg("--crate-type") != Some("proc-macro") + && !matches!(crate_name, Some("proc_macro2" | "quote" | "syn" | "synstructure")) + { + cmd.arg("-Ztls-model=initial-exec"); + } } else { // FIXME(rust-lang/cargo#5754) we shouldn't be using special env vars // here, but rather Cargo should know what flags to pass rustc itself. diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 0ab4824ac0a73..945299d2dcd3c 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1850,7 +1850,7 @@ impl<'a> Builder<'a> { // so we can't use it by default in general, but we can use it for tools // and our own internal libraries. if !mode.must_support_dlopen() && !target.triple.starts_with("powerpc-") { - rustflags.arg("-Ztls-model=initial-exec"); + cargo.env("RUSTC_TLS_MODEL_INITIAL_EXEC", "1"); } if self.config.incremental { diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index ddaa7438e1778..cbdfea89efb8a 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -11,7 +11,7 @@ arrayvec = { version = "0.7", default-features = false } askama = { version = "0.11", default-features = false, features = ["config"] } atty = "0.2" pulldown-cmark = { version = "0.9.2", default-features = false } -minifier = "0.2.1" +minifier = "0.2.2" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" smallvec = "1.8.1" diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index a94520b121926..5441a7bd29ec0 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -551,13 +551,15 @@ where } WherePredicate::EqPredicate { lhs, rhs } => { match lhs { - Type::QPath { ref assoc, ref self_type, ref trait_, .. } => { + Type::QPath(box QPathData { + ref assoc, ref self_type, ref trait_, .. + }) => { let ty = &*self_type; let mut new_trait = trait_.clone(); if self.is_fn_trait(trait_) && assoc.name == sym::Output { ty_to_fn - .entry(*ty.clone()) + .entry(ty.clone()) .and_modify(|e| { *e = (e.0.clone(), Some(rhs.ty().unwrap().clone())) }) @@ -582,7 +584,7 @@ where // to 'T: Iterator' GenericArgs::AngleBracketed { ref mut bindings, .. } => { bindings.push(TypeBinding { - assoc: *assoc.clone(), + assoc: assoc.clone(), kind: TypeBindingKind::Equality { term: rhs }, }); } @@ -596,7 +598,7 @@ where } } - let bounds = ty_to_bounds.entry(*ty.clone()).or_default(); + let bounds = ty_to_bounds.entry(ty.clone()).or_default(); bounds.insert(GenericBound::TraitBound( PolyTrait { trait_: new_trait, generic_params: Vec::new() }, @@ -613,7 +615,7 @@ where )); // Avoid creating any new duplicate bounds later in the outer // loop - ty_to_traits.entry(*ty.clone()).or_default().insert(trait_.clone()); + ty_to_traits.entry(ty.clone()).or_default().insert(trait_.clone()); } _ => panic!("Unexpected LHS {:?} for {:?}", lhs, item_def_id), } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index e56a715e85780..a7048e788b65a 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -62,7 +62,7 @@ pub(crate) fn try_inline( Res::Def(DefKind::Trait, did) => { record_extern_fqn(cx, did, ItemType::Trait); build_impls(cx, Some(parent_module), did, attrs, &mut ret); - clean::TraitItem(build_external_trait(cx, did)) + clean::TraitItem(Box::new(build_external_trait(cx, did))) } Res::Def(DefKind::Fn, did) => { record_extern_fqn(cx, did, ItemType::Function); @@ -672,7 +672,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean: g.where_predicates.retain(|pred| match pred { clean::WherePredicate::BoundPredicate { - ty: clean::QPath { self_type: box clean::Generic(ref s), trait_, .. }, + ty: clean::QPath(box clean::QPathData { self_type: clean::Generic(ref s), trait_, .. }), bounds, .. } => !(bounds.is_empty() || *s == kw::SelfUpper && trait_.def_id() == trait_did), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 971617a840036..5507ffb871b6e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -410,12 +410,12 @@ fn clean_projection<'tcx>( self_type.def_id(&cx.cache) }; let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type); - Type::QPath { - assoc: Box::new(projection_to_path_segment(ty, cx)), + Type::QPath(Box::new(QPathData { + assoc: projection_to_path_segment(ty, cx), should_show_cast, - self_type: Box::new(self_type), + self_type, trait_, - } + })) } fn compute_should_show_cast(self_def_id: Option, trait_: &Path, self_type: &Type) -> bool { @@ -1182,7 +1182,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( .where_predicates .drain_filter(|pred| match *pred { WherePredicate::BoundPredicate { - ty: QPath { ref assoc, ref self_type, ref trait_, .. }, + ty: QPath(box QPathData { ref assoc, ref self_type, ref trait_, .. }), .. } => { if assoc.name != my_name { @@ -1191,7 +1191,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( if trait_.def_id() != assoc_item.container_id(tcx) { return false; } - match **self_type { + match *self_type { Generic(ref s) if *s == kw::SelfUpper => {} _ => return false, } @@ -1324,15 +1324,12 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type let self_def_id = DefId::local(qself.hir_id.owner.local_def_index); let self_type = clean_ty(qself, cx); let should_show_cast = compute_should_show_cast(Some(self_def_id), &trait_, &self_type); - Type::QPath { - assoc: Box::new(clean_path_segment( - p.segments.last().expect("segments were empty"), - cx, - )), + Type::QPath(Box::new(QPathData { + assoc: clean_path_segment(p.segments.last().expect("segments were empty"), cx), should_show_cast, - self_type: Box::new(self_type), + self_type, trait_, - } + })) } hir::QPath::TypeRelative(qself, segment) => { let ty = hir_ty_to_ty(cx.tcx, hir_ty); @@ -1347,12 +1344,12 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type let self_def_id = res.opt_def_id(); let self_type = clean_ty(qself, cx); let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type); - Type::QPath { - assoc: Box::new(clean_path_segment(segment, cx)), + Type::QPath(Box::new(QPathData { + assoc: clean_path_segment(segment, cx), should_show_cast, - self_type: Box::new(self_type), + self_type, trait_, - } + })) } hir::QPath::LangItem(..) => bug!("clean: requiring documentation of lang item"), } @@ -1954,12 +1951,12 @@ fn clean_maybe_renamed_item<'tcx>( .map(|ti| clean_trait_item(cx.tcx.hir().trait_item(ti.id), cx)) .collect(); - TraitItem(Trait { + TraitItem(Box::new(Trait { def_id, items, generics: clean_generics(generics, cx), bounds: bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(), - }) + })) } ItemKind::ExternCrate(orig_name) => { return clean_extern_crate(item, name, orig_name, cx); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 2a38713d43b8a..4c39021903c5b 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -727,7 +727,7 @@ pub(crate) enum ItemKind { OpaqueTyItem(OpaqueTy), StaticItem(Static), ConstantItem(Constant), - TraitItem(Trait), + TraitItem(Box), TraitAliasItem(TraitAlias), ImplItem(Box), /// A required method in a trait declaration meaning it's only a function signature. @@ -1130,7 +1130,7 @@ pub struct RenderedLink { #[derive(Clone, Debug, Default)] pub(crate) struct Attributes { pub(crate) doc_strings: Vec, - pub(crate) other_attrs: Vec, + pub(crate) other_attrs: ast::AttrVec, } impl Attributes { @@ -1173,7 +1173,7 @@ impl Attributes { doc_only: bool, ) -> Attributes { let mut doc_strings = Vec::new(); - let mut other_attrs = Vec::new(); + let mut other_attrs = ast::AttrVec::new(); for (attr, parent_module) in attrs { if let Some((doc_str, comment_kind)) = attr.doc_str_and_comment_kind() { trace!("got doc_str={doc_str:?}"); @@ -1550,13 +1550,7 @@ pub(crate) enum Type { BorrowedRef { lifetime: Option, mutability: Mutability, type_: Box }, /// A qualified path to an associated item: `::Name` - QPath { - assoc: Box, - self_type: Box, - /// FIXME: compute this field on demand. - should_show_cast: bool, - trait_: Path, - }, + QPath(Box), /// A type that is inferred: `_` Infer, @@ -1654,8 +1648,8 @@ impl Type { } pub(crate) fn projection(&self) -> Option<(&Type, DefId, PathSegment)> { - if let QPath { self_type, trait_, assoc, .. } = self { - Some((self_type, trait_.def_id(), *assoc.clone())) + if let QPath(box QPathData { self_type, trait_, assoc, .. }) = self { + Some((self_type, trait_.def_id(), assoc.clone())) } else { None } @@ -1679,7 +1673,7 @@ impl Type { Slice(..) => PrimitiveType::Slice, Array(..) => PrimitiveType::Array, RawPointer(..) => PrimitiveType::RawPointer, - QPath { ref self_type, .. } => return self_type.inner_def_id(cache), + QPath(box QPathData { ref self_type, .. }) => return self_type.inner_def_id(cache), Generic(_) | Infer | ImplTrait(_) => return None, }; cache.and_then(|c| Primitive(t).def_id(c)) @@ -1693,6 +1687,15 @@ impl Type { } } +#[derive(Clone, PartialEq, Eq, Debug, Hash)] +pub(crate) struct QPathData { + pub assoc: PathSegment, + pub self_type: Type, + /// FIXME: compute this field on demand. + pub should_show_cast: bool, + pub trait_: Path, +} + /// A primitive (aka, builtin) type. /// /// This represents things like `i32`, `str`, etc. @@ -2484,11 +2487,11 @@ mod size_asserts { // These are in alphabetical order, which is easy to maintain. static_assert_size!(Crate, 72); // frequently moved by-value static_assert_size!(DocFragment, 32); - static_assert_size!(GenericArg, 80); + static_assert_size!(GenericArg, 64); static_assert_size!(GenericArgs, 32); static_assert_size!(GenericParamDef, 56); static_assert_size!(Item, 56); - static_assert_size!(ItemKind, 112); + static_assert_size!(ItemKind, 96); static_assert_size!(PathSegment, 40); - static_assert_size!(Type, 72); + static_assert_size!(Type, 56); } diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 2b2691e53bbcc..86392610d2c28 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -227,7 +227,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { if let clean::TraitItem(ref t) = *item.kind { self.cache.traits.entry(item.item_id.expect_def_id()).or_insert_with(|| { clean::TraitWithExtraInfo { - trait_: t.clone(), + trait_: *t.clone(), is_notable: item.attrs.has_doc_flag(sym::notable_trait), } }); diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 3dee4d1acc819..b023792e95a58 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1079,7 +1079,12 @@ fn fmt_type<'cx>( write!(f, "impl {}", print_generic_bounds(bounds, cx)) } } - clean::QPath { ref assoc, ref self_type, ref trait_, should_show_cast } => { + clean::QPath(box clean::QPathData { + ref assoc, + ref self_type, + ref trait_, + should_show_cast, + }) => { if f.alternate() { if should_show_cast { write!(f, "<{:#} as {:#}>::", self_type.print(cx), trait_.print(cx))? diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 9d8ee52a3faf8..4a12d74ddef5a 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -111,53 +111,6 @@ fn write_header(out: &mut Buffer, class: &str, extra_content: Option) { write!(out, ""); } -/// Write all the pending elements sharing a same (or at mergeable) `Class`. -/// -/// If there is a "parent" (if a `EnterSpan` event was encountered) and the parent can be merged -/// with the elements' class, then we simply write the elements since the `ExitSpan` event will -/// close the tag. -/// -/// Otherwise, if there is only one pending element, we let the `string` function handle both -/// opening and closing the tag, otherwise we do it into this function. -fn write_pending_elems( - out: &mut Buffer, - href_context: &Option>, - pending_elems: &mut Vec<(&str, Option)>, - current_class: &mut Option, - closing_tags: &[(&str, Class)], -) { - if pending_elems.is_empty() { - return; - } - let mut done = false; - if let Some((_, parent_class)) = closing_tags.last() { - if can_merge(*current_class, Some(*parent_class), "") { - for (text, class) in pending_elems.iter() { - string(out, Escape(text), *class, &href_context, false); - } - done = true; - } - } - if !done { - // We only want to "open" the tag ourselves if we have more than one pending and if the current - // parent tag is not the same as our pending content. - let open_tag_ourselves = pending_elems.len() > 1; - let close_tag = if open_tag_ourselves { - enter_span(out, current_class.unwrap(), &href_context) - } else { - "" - }; - for (text, class) in pending_elems.iter() { - string(out, Escape(text), *class, &href_context, !open_tag_ourselves); - } - if open_tag_ourselves { - exit_span(out, close_tag); - } - } - pending_elems.clear(); - *current_class = None; -} - /// Check if two `Class` can be merged together. In the following rules, "unclassified" means `None` /// basically (since it's `Option`). The following rules apply: /// @@ -171,7 +124,88 @@ fn can_merge(class1: Option, class2: Option, text: &str) -> bool { (Some(c1), Some(c2)) => c1.is_equal_to(c2), (Some(Class::Ident(_)), None) | (None, Some(Class::Ident(_))) => true, (Some(_), None) | (None, Some(_)) => text.trim().is_empty(), - _ => false, + (None, None) => true, + } +} + +/// This type is used as a conveniency to prevent having to pass all its fields as arguments into +/// the various functions (which became its methods). +struct TokenHandler<'a, 'b, 'c, 'd, 'e> { + out: &'a mut Buffer, + /// It contains the closing tag and the associated `Class`. + closing_tags: Vec<(&'static str, Class)>, + /// This is used because we don't automatically generate the closing tag on `ExitSpan` in + /// case an `EnterSpan` event with the same class follows. + pending_exit_span: Option, + /// `current_class` and `pending_elems` are used to group HTML elements with same `class` + /// attributes to reduce the DOM size. + current_class: Option, + /// We need to keep the `Class` for each element because it could contain a `Span` which is + /// used to generate links. + pending_elems: Vec<(&'b str, Option)>, + href_context: Option>, +} + +impl<'a, 'b, 'c, 'd, 'e> TokenHandler<'a, 'b, 'c, 'd, 'e> { + fn handle_exit_span(&mut self) { + // We can't get the last `closing_tags` element using `pop()` because `closing_tags` is + // being used in `write_pending_elems`. + let class = self.closing_tags.last().expect("ExitSpan without EnterSpan").1; + // We flush everything just in case... + self.write_pending_elems(Some(class)); + + exit_span(self.out, self.closing_tags.pop().expect("ExitSpan without EnterSpan").0); + self.pending_exit_span = None; + } + + /// Write all the pending elements sharing a same (or at mergeable) `Class`. + /// + /// If there is a "parent" (if a `EnterSpan` event was encountered) and the parent can be merged + /// with the elements' class, then we simply write the elements since the `ExitSpan` event will + /// close the tag. + /// + /// Otherwise, if there is only one pending element, we let the `string` function handle both + /// opening and closing the tag, otherwise we do it into this function. + /// + /// It returns `true` if `current_class` must be set to `None` afterwards. + fn write_pending_elems(&mut self, current_class: Option) -> bool { + if self.pending_elems.is_empty() { + return false; + } + if let Some((_, parent_class)) = self.closing_tags.last() && + can_merge(current_class, Some(*parent_class), "") + { + for (text, class) in self.pending_elems.iter() { + string(self.out, Escape(text), *class, &self.href_context, false); + } + } else { + // We only want to "open" the tag ourselves if we have more than one pending and if the + // current parent tag is not the same as our pending content. + let close_tag = if self.pending_elems.len() > 1 && current_class.is_some() { + Some(enter_span(self.out, current_class.unwrap(), &self.href_context)) + } else { + None + }; + for (text, class) in self.pending_elems.iter() { + string(self.out, Escape(text), *class, &self.href_context, close_tag.is_none()); + } + if let Some(close_tag) = close_tag { + exit_span(self.out, close_tag); + } + } + self.pending_elems.clear(); + true + } +} + +impl<'a, 'b, 'c, 'd, 'e> Drop for TokenHandler<'a, 'b, 'c, 'd, 'e> { + /// When leaving, we need to flush all pending data to not have missing content. + fn drop(&mut self) { + if self.pending_exit_span.is_some() { + self.handle_exit_span(); + } else { + self.write_pending_elems(self.current_class); + } } } @@ -194,64 +228,72 @@ fn write_code( ) { // This replace allows to fix how the code source with DOS backline characters is displayed. let src = src.replace("\r\n", "\n"); - // It contains the closing tag and the associated `Class`. - let mut closing_tags: Vec<(&'static str, Class)> = Vec::new(); - // The following two variables are used to group HTML elements with same `class` attributes - // to reduce the DOM size. - let mut current_class: Option = None; - // We need to keep the `Class` for each element because it could contain a `Span` which is - // used to generate links. - let mut pending_elems: Vec<(&str, Option)> = Vec::new(); + let mut token_handler = TokenHandler { + out, + closing_tags: Vec::new(), + pending_exit_span: None, + current_class: None, + pending_elems: Vec::new(), + href_context, + }; Classifier::new( &src, - href_context.as_ref().map(|c| c.file_span).unwrap_or(DUMMY_SP), + token_handler.href_context.as_ref().map(|c| c.file_span).unwrap_or(DUMMY_SP), decoration_info, ) .highlight(&mut |highlight| { match highlight { Highlight::Token { text, class } => { + // If we received a `ExitSpan` event and then have a non-compatible `Class`, we + // need to close the ``. + let need_current_class_update = if let Some(pending) = token_handler.pending_exit_span && + !can_merge(Some(pending), class, text) { + token_handler.handle_exit_span(); + true // If the two `Class` are different, time to flush the current content and start // a new one. - if !can_merge(current_class, class, text) { - write_pending_elems( - out, - &href_context, - &mut pending_elems, - &mut current_class, - &closing_tags, - ); - current_class = class.map(Class::dummy); - } else if current_class.is_none() { - current_class = class.map(Class::dummy); + } else if !can_merge(token_handler.current_class, class, text) { + token_handler.write_pending_elems(token_handler.current_class); + true + } else { + token_handler.current_class.is_none() + }; + + if need_current_class_update { + token_handler.current_class = class.map(Class::dummy); } - pending_elems.push((text, class)); + token_handler.pending_elems.push((text, class)); } Highlight::EnterSpan { class } => { - // We flush everything just in case... - write_pending_elems( - out, - &href_context, - &mut pending_elems, - &mut current_class, - &closing_tags, - ); - closing_tags.push((enter_span(out, class, &href_context), class)) + let mut should_add = true; + if let Some(pending_exit_span) = token_handler.pending_exit_span { + if class.is_equal_to(pending_exit_span) { + should_add = false; + } else { + token_handler.handle_exit_span(); + } + } else { + // We flush everything just in case... + if token_handler.write_pending_elems(token_handler.current_class) { + token_handler.current_class = None; + } + } + if should_add { + let closing_tag = enter_span(token_handler.out, class, &token_handler.href_context); + token_handler.closing_tags.push((closing_tag, class)); + } + + token_handler.current_class = None; + token_handler.pending_exit_span = None; } Highlight::ExitSpan => { - // We flush everything just in case... - write_pending_elems( - out, - &href_context, - &mut pending_elems, - &mut current_class, - &closing_tags, - ); - exit_span(out, closing_tags.pop().expect("ExitSpan without EnterSpan").0) + token_handler.current_class = None; + token_handler.pending_exit_span = + Some(token_handler.closing_tags.last().as_ref().expect("ExitSpan without EnterSpan").1); } }; }); - write_pending_elems(out, &href_context, &mut pending_elems, &mut current_class, &closing_tags); } fn write_footer(out: &mut Buffer, playground_button: Option<&str>) { @@ -291,8 +333,8 @@ impl Class { match (self, other) { (Self::Self_(_), Self::Self_(_)) | (Self::Macro(_), Self::Macro(_)) - | (Self::Ident(_), Self::Ident(_)) - | (Self::Decoration(_), Self::Decoration(_)) => true, + | (Self::Ident(_), Self::Ident(_)) => true, + (Self::Decoration(c1), Self::Decoration(c2)) => c1 == c2, (x, y) => x == y, } } @@ -761,7 +803,7 @@ impl<'a> Classifier<'a> { TokenKind::CloseBracket => { if self.in_attribute { self.in_attribute = false; - sink(Highlight::Token { text: "]", class: Some(Class::Attribute) }); + sink(Highlight::Token { text: "]", class: None }); sink(Highlight::ExitSpan); return; } diff --git a/src/librustdoc/html/highlight/fixtures/decorations.html b/src/librustdoc/html/highlight/fixtures/decorations.html index 2184897872153..ebf29f9cb3a91 100644 --- a/src/librustdoc/html/highlight/fixtures/decorations.html +++ b/src/librustdoc/html/highlight/fixtures/decorations.html @@ -1,2 +1,4 @@ -let x = 1; -let y = 2; \ No newline at end of file +let x = 1; +let y = 2; +let z = 3; +let a = 4; \ No newline at end of file diff --git a/src/librustdoc/html/highlight/fixtures/sample.html b/src/librustdoc/html/highlight/fixtures/sample.html index ae2650528eb72..4a5a3cf609cd4 100644 --- a/src/librustdoc/html/highlight/fixtures/sample.html +++ b/src/librustdoc/html/highlight/fixtures/sample.html @@ -8,12 +8,13 @@ .lifetime { color: #B76514; } .question-mark { color: #ff9011; } -
#![crate_type = "lib"]
+
#![crate_type = "lib"]
 
-use std::path::{Path, PathBuf};
+use std::path::{Path, PathBuf};
 
-#[cfg(target_os = "linux")]
-fn main() -> () {
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "windows")]
+fn main() -> () {
     let foo = true && false || true;
     let _: *const () = 0;
     let _ = &foo;
@@ -22,8 +23,8 @@
     mac!(foo, &mut bar);
     assert!(self.length < N && index <= self.length);
     ::std::env::var("gateau").is_ok();
-    #[rustfmt::skip]
-    let s:std::path::PathBuf = std::path::PathBuf::new();
+    #[rustfmt::skip]
+    let s:std::path::PathBuf = std::path::PathBuf::new();
     let mut s = String::new();
 
     match &s {
@@ -31,7 +32,7 @@
     }
 }
 
-macro_rules! bar {
+macro_rules! bar {
     ($foo:tt) => {};
 }
 
diff --git a/src/librustdoc/html/highlight/fixtures/sample.rs b/src/librustdoc/html/highlight/fixtures/sample.rs index fbfdc6767337c..ef85b566cb3c4 100644 --- a/src/librustdoc/html/highlight/fixtures/sample.rs +++ b/src/librustdoc/html/highlight/fixtures/sample.rs @@ -3,6 +3,7 @@ use std::path::{Path, PathBuf}; #[cfg(target_os = "linux")] +#[cfg(target_os = "windows")] fn main() -> () { let foo = true && false || true; let _: *const () = 0; diff --git a/src/librustdoc/html/highlight/tests.rs b/src/librustdoc/html/highlight/tests.rs index 4861a8ad32da6..a5e633df43448 100644 --- a/src/librustdoc/html/highlight/tests.rs +++ b/src/librustdoc/html/highlight/tests.rs @@ -69,9 +69,12 @@ fn test_union_highlighting() { fn test_decorations() { create_default_session_globals_then(|| { let src = "let x = 1; -let y = 2;"; +let y = 2; +let z = 3; +let a = 4;"; let mut decorations = FxHashMap::default(); - decorations.insert("example", vec![(0, 10)]); + decorations.insert("example", vec![(0, 10), (11, 21)]); + decorations.insert("example2", vec![(22, 32)]); let mut html = Buffer::new(); write_code(&mut html, src, None, Some(DecorationInfo(decorations))); diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 2b66ab22475d4..f9d6b4619cc77 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2632,8 +2632,8 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec { clean::Type::BorrowedRef { type_, .. } => { work.push_back(*type_); } - clean::Type::QPath { self_type, trait_, .. } => { - work.push_back(*self_type); + clean::Type::QPath(box clean::QPathData { self_type, trait_, .. }) => { + work.push_back(self_type); process_path(trait_.def_id()); } _ => {} diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 1fedb0144d1d0..c4e8b6f5f8449 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -248,7 +248,7 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum { VariantItem(v) => ItemEnum::Variant(v.into_tcx(tcx)), FunctionItem(f) => ItemEnum::Function(from_function(f, header.unwrap(), tcx)), ForeignFunctionItem(f) => ItemEnum::Function(from_function(f, header.unwrap(), tcx)), - TraitItem(t) => ItemEnum::Trait(t.into_tcx(tcx)), + TraitItem(t) => ItemEnum::Trait((*t).into_tcx(tcx)), TraitAliasItem(t) => ItemEnum::TraitAlias(t.into_tcx(tcx)), MethodItem(m, _) => ItemEnum::Method(from_function_method(m, true, header.unwrap(), tcx)), TyMethodItem(m) => ItemEnum::Method(from_function_method(m, false, header.unwrap(), tcx)), @@ -480,10 +480,10 @@ impl FromWithTcx for Type { mutable: mutability == ast::Mutability::Mut, type_: Box::new((*type_).into_tcx(tcx)), }, - QPath { assoc, self_type, trait_, .. } => Type::QualifiedPath { + QPath(box clean::QPathData { assoc, self_type, trait_, .. }) => Type::QualifiedPath { name: assoc.name.to_string(), args: Box::new(assoc.args.clone().into_tcx(tcx)), - self_type: Box::new((*self_type).into_tcx(tcx)), + self_type: Box::new(self_type.into_tcx(tcx)), trait_: trait_.into_tcx(tcx), }, } diff --git a/src/test/assembly/x86_64-floating-point-clamp.rs b/src/test/assembly/x86_64-floating-point-clamp.rs new file mode 100644 index 0000000000000..0f3b465d08d4f --- /dev/null +++ b/src/test/assembly/x86_64-floating-point-clamp.rs @@ -0,0 +1,25 @@ +// Floating-point clamp is designed to be implementable as max+min, +// so check to make sure that's what it's actually emitting. + +// assembly-output: emit-asm +// compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel +// only-x86_64 + +// CHECK-LABEL: clamp_demo: +#[no_mangle] +pub fn clamp_demo(a: f32, x: f32, y: f32) -> f32 { + // CHECK: maxss + // CHECK: minss + a.clamp(x, y) +} + +// CHECK-LABEL: clamp12_demo: +#[no_mangle] +pub fn clamp12_demo(a: f32) -> f32 { + // CHECK: movss xmm1 + // CHECK-NEXT: maxss xmm1, xmm0 + // CHECK-NEXT: movss xmm0 + // CHECK-NEXT: minss xmm0, xmm1 + // CHECK: ret + a.clamp(1.0, 2.0) +} diff --git a/src/test/codegen/pic-relocation-model.rs b/src/test/codegen/pic-relocation-model.rs index 6e1d5a6c3f271..bcfe2f9af50bd 100644 --- a/src/test/codegen/pic-relocation-model.rs +++ b/src/test/codegen/pic-relocation-model.rs @@ -13,4 +13,4 @@ pub fn call_foreign_fn() -> u8 { // CHECK: declare zeroext i8 @foreign_fn() extern "C" {fn foreign_fn() -> u8;} -// CHECK: !{i32 7, !"PIC Level", i32 2} +// CHECK: !{i32 {{[78]}}, !"PIC Level", i32 2} diff --git a/src/test/codegen/pie-relocation-model.rs b/src/test/codegen/pie-relocation-model.rs index a843202a94f82..ec44edc066774 100644 --- a/src/test/codegen/pie-relocation-model.rs +++ b/src/test/codegen/pie-relocation-model.rs @@ -18,5 +18,5 @@ pub fn call_foreign_fn() -> u8 { // CHECK: declare zeroext i8 @foreign_fn() extern "C" {fn foreign_fn() -> u8;} -// CHECK: !{i32 7, !"PIC Level", i32 2} +// CHECK: !{i32 {{[78]}}, !"PIC Level", i32 2} // CHECK: !{i32 7, !"PIE Level", i32 2} diff --git a/src/test/rustdoc/issue-41783.codeblock.html b/src/test/rustdoc/issue-41783.codeblock.html index b919935e4b47a..89987491d1b46 100644 --- a/src/test/rustdoc/issue-41783.codeblock.html +++ b/src/test/rustdoc/issue-41783.codeblock.html @@ -1,5 +1,5 @@ # single ## double ### triple -#[outer] -#![inner] \ No newline at end of file +#[outer] +#![inner]
diff --git a/src/test/rustdoc/issue-41783.rs b/src/test/rustdoc/issue-41783.rs index d67716028799b..87267a750c615 100644 --- a/src/test/rustdoc/issue-41783.rs +++ b/src/test/rustdoc/issue-41783.rs @@ -1,8 +1,10 @@ // @has issue_41783/struct.Foo.html // @!hasraw - 'space' // @!hasraw - 'comment' -// @hasraw - '#[outer]' -// @hasraw - '#![inner]' +// @hasraw - '#[outer]' +// @!hasraw - '#[outer]' +// @hasraw - '#![inner]' +// @!hasraw - '#![inner]' // @snapshot 'codeblock' - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]//pre/code' /// ```no_run diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.rs b/src/test/ui-fulldeps/internal-lints/diagnostics.rs index d6f63d44ba6a8..33192433bbf38 100644 --- a/src/test/ui-fulldeps/internal-lints/diagnostics.rs +++ b/src/test/ui-fulldeps/internal-lints/diagnostics.rs @@ -16,7 +16,7 @@ use rustc_session::{parse::ParseSess, SessionDiagnostic}; use rustc_span::Span; #[derive(SessionDiagnostic)] -#[error(parser::expect_path)] +#[diag(parser::expect_path)] struct DeriveSessionDiagnostic { #[primary_span] span: Span, diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs index 0d9c9350efca4..117b798710cf0 100644 --- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs +++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs @@ -30,7 +30,6 @@ use rustc_ast::mut_visit::{self, visit_clobber, MutVisitor}; use rustc_ast::ptr::P; use rustc_ast::*; use rustc_ast_pretty::pprust; -use rustc_data_structures::thin_vec::ThinVec; use rustc_parse::new_parser_from_source_str; use rustc_session::parse::ParseSess; use rustc_span::source_map::FilePathMapping; @@ -47,7 +46,7 @@ fn parse_expr(ps: &ParseSess, src: &str) -> Option> { // Helper functions for building exprs fn expr(kind: ExprKind) -> P { - P(Expr { id: DUMMY_NODE_ID, kind, span: DUMMY_SP, attrs: ThinVec::new(), tokens: None }) + P(Expr { id: DUMMY_NODE_ID, kind, span: DUMMY_SP, attrs: AttrVec::new(), tokens: None }) } fn make_x() -> P { @@ -196,7 +195,7 @@ impl MutVisitor for AddParens { id: DUMMY_NODE_ID, kind: ExprKind::Paren(e), span: DUMMY_SP, - attrs: ThinVec::new(), + attrs: AttrVec::new(), tokens: None, }) }); diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 0a210cbdc9430..aaa8caa64f343 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -28,15 +28,15 @@ use rustc_errors::{Applicability, MultiSpan}; extern crate rustc_session; #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct Hello {} #[derive(SessionDiagnostic)] -#[warning(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct HelloWarn {} #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] //~^ ERROR `#[derive(SessionDiagnostic)]` can only be used on structs enum SessionDiagnosticOnEnum { Foo, @@ -44,54 +44,54 @@ enum SessionDiagnosticOnEnum { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] -#[error = "E0123"] -//~^ ERROR `#[error = ...]` is not a valid attribute +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag = "E0123"] +//~^ ERROR `#[diag = ...]` is not a valid attribute struct WrongStructAttrStyle {} #[derive(SessionDiagnostic)] #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] //~^ ERROR `#[nonsense(...)]` is not a valid attribute -//~^^ ERROR diagnostic kind not specified +//~^^ ERROR diagnostic slug not specified //~^^^ ERROR cannot find attribute `nonsense` in this scope struct InvalidStructAttr {} #[derive(SessionDiagnostic)] -#[error("E0123")] -//~^ ERROR `#[error("...")]` is not a valid attribute +#[diag("E0123")] +//~^ ERROR `#[diag("...")]` is not a valid attribute //~^^ ERROR diagnostic slug not specified struct InvalidLitNestedAttr {} #[derive(SessionDiagnostic)] -#[error(nonsense, code = "E0123")] +#[diag(nonsense, code = "E0123")] //~^ ERROR cannot find value `nonsense` in module `rustc_errors::fluent` struct InvalidNestedStructAttr {} #[derive(SessionDiagnostic)] -#[error(nonsense("foo"), code = "E0123", slug = "foo")] -//~^ ERROR `#[error(nonsense(...))]` is not a valid attribute +#[diag(nonsense("foo"), code = "E0123", slug = "foo")] +//~^ ERROR `#[diag(nonsense(...))]` is not a valid attribute //~^^ ERROR diagnostic slug not specified struct InvalidNestedStructAttr1 {} #[derive(SessionDiagnostic)] -#[error(nonsense = "...", code = "E0123", slug = "foo")] -//~^ ERROR `#[error(nonsense = ...)]` is not a valid attribute +#[diag(nonsense = "...", code = "E0123", slug = "foo")] +//~^ ERROR `#[diag(nonsense = ...)]` is not a valid attribute //~^^ ERROR diagnostic slug not specified struct InvalidNestedStructAttr2 {} #[derive(SessionDiagnostic)] -#[error(nonsense = 4, code = "E0123", slug = "foo")] -//~^ ERROR `#[error(nonsense = ...)]` is not a valid attribute +#[diag(nonsense = 4, code = "E0123", slug = "foo")] +//~^ ERROR `#[diag(nonsense = ...)]` is not a valid attribute //~^^ ERROR diagnostic slug not specified struct InvalidNestedStructAttr3 {} #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")] -//~^ ERROR `#[error(slug = ...)]` is not a valid attribute +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")] +//~^ ERROR `#[diag(slug = ...)]` is not a valid attribute struct InvalidNestedStructAttr4 {} #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct WrongPlaceField { #[suggestion = "bar"] //~^ ERROR `#[suggestion = ...]` is not a valid attribute @@ -99,45 +99,36 @@ struct WrongPlaceField { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] -#[error(typeck::ambiguous_lifetime_bound, code = "E0456")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0456")] //~^ ERROR specified multiple times //~^^ ERROR specified multiple times -//~^^^ ERROR specified multiple times -struct ErrorSpecifiedTwice {} +struct DiagSpecifiedTwice {} #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] -#[warning(typeck::ambiguous_lifetime_bound, code = "E0293")] -//~^ ERROR specified multiple times -//~^^ ERROR specified multiple times -//~^^^ ERROR specified multiple times -struct WarnSpecifiedAfterError {} - -#[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] //~^ ERROR specified multiple times struct CodeSpecifiedTwice {} #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")] -//~^ ERROR `#[error(typeck::ambiguous_lifetime_bound)]` is not a valid attribute +#[diag(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")] +//~^ ERROR `#[diag(typeck::ambiguous_lifetime_bound)]` is not a valid attribute struct SlugSpecifiedTwice {} #[derive(SessionDiagnostic)] -struct KindNotProvided {} //~ ERROR diagnostic kind not specified +struct KindNotProvided {} //~ ERROR diagnostic slug not specified #[derive(SessionDiagnostic)] -#[error(code = "E0456")] +#[diag(code = "E0456")] //~^ ERROR diagnostic slug not specified struct SlugNotProvided {} #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound)] +#[diag(typeck::ambiguous_lifetime_bound)] struct CodeNotProvided {} #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct MessageWrongType { #[primary_span] //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` @@ -145,7 +136,7 @@ struct MessageWrongType { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct InvalidPathFieldAttr { #[nonsense] //~^ ERROR `#[nonsense]` is not a valid attribute @@ -154,7 +145,7 @@ struct InvalidPathFieldAttr { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithField { name: String, #[label(typeck::label)] @@ -162,7 +153,7 @@ struct ErrorWithField { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithMessageAppliedToField { #[label(typeck::label)] //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` @@ -170,7 +161,7 @@ struct ErrorWithMessageAppliedToField { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithNonexistentField { #[suggestion(typeck::suggestion, code = "{name}")] //~^ ERROR `name` doesn't refer to a field on this type @@ -179,7 +170,7 @@ struct ErrorWithNonexistentField { #[derive(SessionDiagnostic)] //~^ ERROR invalid format string: expected `'}'` -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorMissingClosingBrace { #[suggestion(typeck::suggestion, code = "{name")] suggestion: (Span, Applicability), @@ -189,7 +180,7 @@ struct ErrorMissingClosingBrace { #[derive(SessionDiagnostic)] //~^ ERROR invalid format string: unmatched `}` -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorMissingOpeningBrace { #[suggestion(typeck::suggestion, code = "name}")] suggestion: (Span, Applicability), @@ -198,14 +189,14 @@ struct ErrorMissingOpeningBrace { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct LabelOnSpan { #[label(typeck::label)] sp: Span, } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct LabelOnNonSpan { #[label(typeck::label)] //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` @@ -213,7 +204,7 @@ struct LabelOnNonSpan { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct Suggest { #[suggestion(typeck::suggestion, code = "This is the suggested code")] #[suggestion_short(typeck::suggestion, code = "This is the suggested code")] @@ -223,14 +214,14 @@ struct Suggest { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithoutCode { #[suggestion(typeck::suggestion)] suggestion: (Span, Applicability), } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithBadKey { #[suggestion(nonsense = "bar")] //~^ ERROR `#[suggestion(nonsense = ...)]` is not a valid attribute @@ -238,7 +229,7 @@ struct SuggestWithBadKey { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithShorthandMsg { #[suggestion(msg = "bar")] //~^ ERROR `#[suggestion(msg = ...)]` is not a valid attribute @@ -246,21 +237,21 @@ struct SuggestWithShorthandMsg { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithoutMsg { #[suggestion(code = "bar")] suggestion: (Span, Applicability), } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithTypesSwapped { #[suggestion(typeck::suggestion, code = "This is suggested code")] suggestion: (Applicability, Span), } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithWrongTypeApplicabilityOnly { #[suggestion(typeck::suggestion, code = "This is suggested code")] //~^ ERROR wrong field type for suggestion @@ -268,14 +259,14 @@ struct SuggestWithWrongTypeApplicabilityOnly { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithSpanOnly { #[suggestion(typeck::suggestion, code = "This is suggested code")] suggestion: Span, } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithDuplicateSpanAndApplicability { #[suggestion(typeck::suggestion, code = "This is suggested code")] //~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one `Span` @@ -283,7 +274,7 @@ struct SuggestWithDuplicateSpanAndApplicability { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithDuplicateApplicabilityAndSpan { #[suggestion(typeck::suggestion, code = "This is suggested code")] //~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one @@ -291,7 +282,7 @@ struct SuggestWithDuplicateApplicabilityAndSpan { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct WrongKindOfAnnotation { #[label = "bar"] //~^ ERROR `#[label = ...]` is not a valid attribute @@ -299,7 +290,7 @@ struct WrongKindOfAnnotation { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct OptionsInErrors { #[label(typeck::label)] label: Option, @@ -308,7 +299,7 @@ struct OptionsInErrors { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0456")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0456")] struct MoveOutOfBorrowError<'tcx> { name: Ident, ty: Ty<'tcx>, @@ -322,7 +313,7 @@ struct MoveOutOfBorrowError<'tcx> { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithLifetime<'a> { #[label(typeck::label)] span: Span, @@ -330,7 +321,7 @@ struct ErrorWithLifetime<'a> { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithDefaultLabelAttr<'a> { #[label] span: Span, @@ -339,7 +330,7 @@ struct ErrorWithDefaultLabelAttr<'a> { #[derive(SessionDiagnostic)] //~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ArgFieldWithoutSkip { #[primary_span] span: Span, @@ -347,7 +338,7 @@ struct ArgFieldWithoutSkip { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ArgFieldWithSkip { #[primary_span] span: Span, @@ -358,56 +349,56 @@ struct ArgFieldWithSkip { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithSpannedNote { #[note] span: Span, } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithSpannedNoteCustom { #[note(typeck::note)] span: Span, } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] #[note] struct ErrorWithNote { val: String, } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] #[note(typeck::note)] struct ErrorWithNoteCustom { val: String, } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithSpannedHelp { #[help] span: Span, } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithSpannedHelpCustom { #[help(typeck::help)] span: Span, } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] #[help] struct ErrorWithHelp { val: String, } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] #[help(typeck::help)] struct ErrorWithHelpCustom { val: String, @@ -415,34 +406,34 @@ struct ErrorWithHelpCustom { #[derive(SessionDiagnostic)] #[help] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithHelpWrongOrder { val: String, } #[derive(SessionDiagnostic)] #[help(typeck::help)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithHelpCustomWrongOrder { val: String, } #[derive(SessionDiagnostic)] #[note] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithNoteWrongOrder { val: String, } #[derive(SessionDiagnostic)] #[note(typeck::note)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithNoteCustomWrongOrder { val: String, } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ApplicabilityInBoth { #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] //~^ ERROR applicability cannot be set in both the field and attribute @@ -450,7 +441,7 @@ struct ApplicabilityInBoth { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct InvalidApplicability { #[suggestion(typeck::suggestion, code = "...", applicability = "batman")] //~^ ERROR invalid applicability @@ -458,14 +449,14 @@ struct InvalidApplicability { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ValidApplicability { #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] suggestion: Span, } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct NoApplicability { #[suggestion(typeck::suggestion, code = "...")] suggestion: Span, @@ -476,14 +467,14 @@ struct NoApplicability { struct Note; #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound)] +#[diag(typeck::ambiguous_lifetime_bound)] struct Subdiagnostic { #[subdiagnostic] note: Note, } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct VecField { #[primary_span] #[label] @@ -491,7 +482,7 @@ struct VecField { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct UnitField { #[primary_span] spans: Span, @@ -502,7 +493,7 @@ struct UnitField { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct OptUnitField { #[primary_span] spans: Span, @@ -513,7 +504,7 @@ struct OptUnitField { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct LabelWithTrailingPath { #[label(typeck::label, foo)] //~^ ERROR `#[label(...)]` is not a valid attribute @@ -521,7 +512,7 @@ struct LabelWithTrailingPath { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct LabelWithTrailingNameValue { #[label(typeck::label, foo = "...")] //~^ ERROR `#[label(...)]` is not a valid attribute @@ -529,40 +520,64 @@ struct LabelWithTrailingNameValue { } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct LabelWithTrailingList { #[label(typeck::label, foo("..."))] //~^ ERROR `#[label(...)]` is not a valid attribute span: Span, } -#[derive(SessionDiagnostic)] -#[lint(typeck::ambiguous_lifetime_bound)] -//~^ ERROR only `#[error(..)]` and `#[warning(..)]` are supported -struct LintsBad { -} - #[derive(LintDiagnostic)] -#[lint(typeck::ambiguous_lifetime_bound)] +#[diag(typeck::ambiguous_lifetime_bound)] struct LintsGood { } #[derive(LintDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound)] -//~^ ERROR only `#[lint(..)]` is supported -struct ErrorsBad { +#[diag(typeck::ambiguous_lifetime_bound)] +struct PrimarySpanOnLint { + #[primary_span] + //~^ ERROR `#[primary_span]` is not a valid attribute + span: Span, } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithMultiSpan { #[primary_span] span: MultiSpan, } #[derive(SessionDiagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] #[warn_] struct ErrorWithWarn { val: String, } + +#[derive(SessionDiagnostic)] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +//~^ ERROR `#[error(...)]` is not a valid attribute +//~| ERROR diagnostic slug not specified +//~| ERROR cannot find attribute `error` in this scope +struct ErrorAttribute {} + +#[derive(SessionDiagnostic)] +#[warning(typeck::ambiguous_lifetime_bound, code = "E0123")] +//~^ ERROR `#[warning(...)]` is not a valid attribute +//~| ERROR diagnostic slug not specified +//~| ERROR cannot find attribute `warning` in this scope +struct WarningAttribute {} + +#[derive(SessionDiagnostic)] +#[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] +//~^ ERROR `#[lint(...)]` is not a valid attribute +//~| ERROR diagnostic slug not specified +//~| ERROR cannot find attribute `lint` in this scope +struct LintAttributeOnSessionDiag {} + +#[derive(LintDiagnostic)] +#[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] +//~^ ERROR `#[lint(...)]` is not a valid attribute +//~| ERROR diagnostic slug not specified +//~| ERROR cannot find attribute `lint` in this scope +struct LintAttributeOnLintDiag {} diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index c1080aa24521f..866b1a1de999c 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -1,7 +1,7 @@ error: `#[derive(SessionDiagnostic)]` can only be used on structs --> $DIR/diagnostic-derive.rs:39:1 | -LL | / #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | / #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] LL | | LL | | enum SessionDiagnosticOnEnum { LL | | Foo, @@ -9,11 +9,11 @@ LL | | Bar, LL | | } | |_^ -error: `#[error = ...]` is not a valid attribute +error: `#[diag = ...]` is not a valid attribute --> $DIR/diagnostic-derive.rs:48:1 | -LL | #[error = "E0123"] - | ^^^^^^^^^^^^^^^^^^ +LL | #[diag = "E0123"] + | ^^^^^^^^^^^^^^^^^ error: `#[nonsense(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:53:1 @@ -21,9 +21,9 @@ error: `#[nonsense(...)]` is not a valid attribute LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: only `error`, `warning`, `help`, `note` and `warn_` are valid attributes + = help: only `diag`, `help`, `note` and `warn_` are valid attributes -error: diagnostic kind not specified +error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:53:1 | LL | / #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] @@ -33,89 +33,89 @@ LL | | LL | | struct InvalidStructAttr {} | |___________________________^ | - = help: use the `#[error(...)]` attribute to create an error + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` -error: `#[error("...")]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:60:9 +error: `#[diag("...")]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:60:8 | -LL | #[error("E0123")] - | ^^^^^^^ +LL | #[diag("E0123")] + | ^^^^^^^ | = help: first argument of the attribute should be the diagnostic slug error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:60:1 | -LL | / #[error("E0123")] +LL | / #[diag("E0123")] LL | | LL | | LL | | struct InvalidLitNestedAttr {} | |______________________________^ | - = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` -error: `#[error(nonsense(...))]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:71:9 +error: `#[diag(nonsense(...))]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:71:8 | -LL | #[error(nonsense("foo"), code = "E0123", slug = "foo")] - | ^^^^^^^^^^^^^^^ +LL | #[diag(nonsense("foo"), code = "E0123", slug = "foo")] + | ^^^^^^^^^^^^^^^ | = help: first argument of the attribute should be the diagnostic slug error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:71:1 | -LL | / #[error(nonsense("foo"), code = "E0123", slug = "foo")] +LL | / #[diag(nonsense("foo"), code = "E0123", slug = "foo")] LL | | LL | | LL | | struct InvalidNestedStructAttr1 {} | |__________________________________^ | - = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` -error: `#[error(nonsense = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:77:9 +error: `#[diag(nonsense = ...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:77:8 | -LL | #[error(nonsense = "...", code = "E0123", slug = "foo")] - | ^^^^^^^^^^^^^^^^ +LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")] + | ^^^^^^^^^^^^^^^^ | = help: first argument of the attribute should be the diagnostic slug error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:77:1 | -LL | / #[error(nonsense = "...", code = "E0123", slug = "foo")] +LL | / #[diag(nonsense = "...", code = "E0123", slug = "foo")] LL | | LL | | LL | | struct InvalidNestedStructAttr2 {} | |__________________________________^ | - = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` -error: `#[error(nonsense = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:83:9 +error: `#[diag(nonsense = ...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:83:8 | -LL | #[error(nonsense = 4, code = "E0123", slug = "foo")] - | ^^^^^^^^^^^^ +LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")] + | ^^^^^^^^^^^^ | = help: first argument of the attribute should be the diagnostic slug error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:83:1 | -LL | / #[error(nonsense = 4, code = "E0123", slug = "foo")] +LL | / #[diag(nonsense = 4, code = "E0123", slug = "foo")] LL | | LL | | LL | | struct InvalidNestedStructAttr3 {} | |__________________________________^ | - = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` -error: `#[error(slug = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:89:59 +error: `#[diag(slug = ...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:89:58 | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")] - | ^^^^^^^^^^^^ +LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")] + | ^^^^^^^^^^^^ | = help: only `code` is a valid nested attributes following the slug @@ -128,119 +128,71 @@ LL | #[suggestion = "bar"] error: specified multiple times --> $DIR/diagnostic-derive.rs:103:1 | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here --> $DIR/diagnostic-derive.rs:102:1 | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:103:1 + --> $DIR/diagnostic-derive.rs:103:49 | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456")] + | ^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:102:1 + --> $DIR/diagnostic-derive.rs:102:49 | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:103:50 + --> $DIR/diagnostic-derive.rs:109:65 | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")] - | ^^^^^^^ +LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] + | ^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:102:50 + --> $DIR/diagnostic-derive.rs:109:49 | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^ +LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] + | ^^^^^^^ -error: specified multiple times - --> $DIR/diagnostic-derive.rs:111:1 +error: `#[diag(typeck::ambiguous_lifetime_bound)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:114:42 | -LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:110:1 - | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[diag(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: specified multiple times - --> $DIR/diagnostic-derive.rs:111:1 - | -LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:110:1 - | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: specified multiple times - --> $DIR/diagnostic-derive.rs:111:52 - | -LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")] - | ^^^^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:110:50 - | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^ - -error: specified multiple times - --> $DIR/diagnostic-derive.rs:118:66 - | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] - | ^^^^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:118:50 - | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] - | ^^^^^^^ - -error: `#[error(typeck::ambiguous_lifetime_bound)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:123:43 - | -LL | #[error(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: diagnostic kind not specified - --> $DIR/diagnostic-derive.rs:128:1 +error: diagnostic slug not specified + --> $DIR/diagnostic-derive.rs:119:1 | LL | struct KindNotProvided {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: use the `#[error(...)]` attribute to create an error + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:131:1 + --> $DIR/diagnostic-derive.rs:122:1 | -LL | / #[error(code = "E0456")] +LL | / #[diag(code = "E0456")] LL | | LL | | struct SlugNotProvided {} | |_________________________^ | - = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:142:5 + --> $DIR/diagnostic-derive.rs:133:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ error: `#[nonsense]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:150:5 + --> $DIR/diagnostic-derive.rs:141:5 | LL | #[nonsense] | ^^^^^^^^^^^ @@ -248,19 +200,19 @@ LL | #[nonsense] = help: only `skip_arg`, `primary_span`, `label`, `note`, `help` and `subdiagnostic` are valid field attributes error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:167:5 + --> $DIR/diagnostic-derive.rs:158:5 | LL | #[label(typeck::label)] | ^^^^^^^^^^^^^^^^^^^^^^^ error: `name` doesn't refer to a field on this type - --> $DIR/diagnostic-derive.rs:175:45 + --> $DIR/diagnostic-derive.rs:166:45 | LL | #[suggestion(typeck::suggestion, code = "{name}")] | ^^^^^^^^ error: invalid format string: expected `'}'` but string was terminated - --> $DIR/diagnostic-derive.rs:180:16 + --> $DIR/diagnostic-derive.rs:171:16 | LL | #[derive(SessionDiagnostic)] | - ^ expected `'}'` in format string @@ -271,7 +223,7 @@ LL | #[derive(SessionDiagnostic)] = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid format string: unmatched `}` found - --> $DIR/diagnostic-derive.rs:190:15 + --> $DIR/diagnostic-derive.rs:181:15 | LL | #[derive(SessionDiagnostic)] | ^ unmatched `}` in format string @@ -280,13 +232,13 @@ LL | #[derive(SessionDiagnostic)] = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:210:5 + --> $DIR/diagnostic-derive.rs:201:5 | LL | #[label(typeck::label)] | ^^^^^^^^^^^^^^^^^^^^^^^ error: `#[suggestion(nonsense = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:235:18 + --> $DIR/diagnostic-derive.rs:226:18 | LL | #[suggestion(nonsense = "bar")] | ^^^^^^^^^^^^^^^^ @@ -294,7 +246,7 @@ LL | #[suggestion(nonsense = "bar")] = help: only `message`, `code` and `applicability` are valid field attributes error: `#[suggestion(msg = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:243:18 + --> $DIR/diagnostic-derive.rs:234:18 | LL | #[suggestion(msg = "bar")] | ^^^^^^^^^^^ @@ -302,7 +254,7 @@ LL | #[suggestion(msg = "bar")] = help: only `message`, `code` and `applicability` are valid field attributes error: wrong field type for suggestion - --> $DIR/diagnostic-derive.rs:265:5 + --> $DIR/diagnostic-derive.rs:256:5 | LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")] LL | | @@ -312,7 +264,7 @@ LL | | suggestion: Applicability, = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)` error: type of field annotated with `#[suggestion(...)]` contains more than one `Span` - --> $DIR/diagnostic-derive.rs:280:5 + --> $DIR/diagnostic-derive.rs:271:5 | LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")] LL | | @@ -320,7 +272,7 @@ LL | | suggestion: (Span, Span, Applicability), | |___________________________________________^ error: type of field annotated with `#[suggestion(...)]` contains more than one Applicability - --> $DIR/diagnostic-derive.rs:288:5 + --> $DIR/diagnostic-derive.rs:279:5 | LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")] LL | | @@ -328,62 +280,128 @@ LL | | suggestion: (Applicability, Applicability, Span), | |____________________________________________________^ error: `#[label = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:296:5 + --> $DIR/diagnostic-derive.rs:287:5 | LL | #[label = "bar"] | ^^^^^^^^^^^^^^^^ error: applicability cannot be set in both the field and attribute - --> $DIR/diagnostic-derive.rs:447:52 + --> $DIR/diagnostic-derive.rs:438:52 | LL | #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: invalid applicability - --> $DIR/diagnostic-derive.rs:455:52 + --> $DIR/diagnostic-derive.rs:446:52 | LL | #[suggestion(typeck::suggestion, code = "...", applicability = "batman")] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[label(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:518:5 + --> $DIR/diagnostic-derive.rs:509:5 | LL | #[label(typeck::label, foo)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[label(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:526:5 + --> $DIR/diagnostic-derive.rs:517:5 | LL | #[label(typeck::label, foo = "...")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[label(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:534:5 + --> $DIR/diagnostic-derive.rs:525:5 | LL | #[label(typeck::label, foo("..."))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: only `#[error(..)]` and `#[warning(..)]` are supported - --> $DIR/diagnostic-derive.rs:540:1 +error: `#[primary_span]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:538:5 | -LL | / #[lint(typeck::ambiguous_lifetime_bound)] +LL | #[primary_span] + | ^^^^^^^^^^^^^^^ + | + = help: the `primary_span` field attribute is not valid for lint diagnostics + +error: `#[error(...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:558:1 + | +LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `error`, `warning` and `lint` have been replaced by `diag` + +error: diagnostic slug not specified + --> $DIR/diagnostic-derive.rs:558:1 + | +LL | / #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] LL | | -LL | | struct LintsBad { -LL | | } - | |_^ +LL | | +LL | | +LL | | struct ErrorAttribute {} + | |________________________^ + | + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + +error: `#[warning(...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:565:1 | - = help: use the `#[error(...)]` attribute to create a error +LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `error`, `warning` and `lint` have been replaced by `diag` -error: only `#[lint(..)]` is supported - --> $DIR/diagnostic-derive.rs:551:1 +error: diagnostic slug not specified + --> $DIR/diagnostic-derive.rs:565:1 | -LL | / #[error(typeck::ambiguous_lifetime_bound)] +LL | / #[warning(typeck::ambiguous_lifetime_bound, code = "E0123")] LL | | -LL | | struct ErrorsBad { -LL | | } - | |_^ +LL | | +LL | | +LL | | struct WarningAttribute {} + | |__________________________^ + | + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + +error: `#[lint(...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:572:1 + | +LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `error`, `warning` and `lint` have been replaced by `diag` + +error: diagnostic slug not specified + --> $DIR/diagnostic-derive.rs:572:1 + | +LL | / #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | | +LL | | +LL | | +LL | | struct LintAttributeOnSessionDiag {} + | |____________________________________^ + | + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + +error: `#[lint(...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:579:1 + | +LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `error`, `warning` and `lint` have been replaced by `diag` + +error: diagnostic slug not specified + --> $DIR/diagnostic-derive.rs:579:1 + | +LL | / #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | | +LL | | +LL | | +LL | | struct LintAttributeOnLintDiag {} + | |_________________________________^ | - = help: use the `#[lint(...)]` attribute to create a lint + = help: specify the slug as the first argument to the attribute, such as `#[diag(typeck::example_error)]` error: cannot find attribute `nonsense` in this scope --> $DIR/diagnostic-derive.rs:53:3 @@ -392,32 +410,56 @@ LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] | ^^^^^^^^ error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive.rs:150:7 + --> $DIR/diagnostic-derive.rs:141:7 | LL | #[nonsense] | ^^^^^^^^ +error: cannot find attribute `error` in this scope + --> $DIR/diagnostic-derive.rs:558:3 + | +LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^ + +error: cannot find attribute `warning` in this scope + --> $DIR/diagnostic-derive.rs:565:3 + | +LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^^^ + +error: cannot find attribute `lint` in this scope + --> $DIR/diagnostic-derive.rs:572:3 + | +LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^ help: a built-in attribute with a similar name exists: `link` + +error: cannot find attribute `lint` in this scope + --> $DIR/diagnostic-derive.rs:579:3 + | +LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^ help: a built-in attribute with a similar name exists: `link` + error[E0425]: cannot find value `nonsense` in module `rustc_errors::fluent` - --> $DIR/diagnostic-derive.rs:66:9 + --> $DIR/diagnostic-derive.rs:66:8 | -LL | #[error(nonsense, code = "E0123")] - | ^^^^^^^^ not found in `rustc_errors::fluent` +LL | #[diag(nonsense, code = "E0123")] + | ^^^^^^^^ not found in `rustc_errors::fluent` error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied - --> $DIR/diagnostic-derive.rs:340:10 + --> $DIR/diagnostic-derive.rs:331:10 | LL | #[derive(SessionDiagnostic)] | ^^^^^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello` | = help: normalized in stderr note: required by a bound in `DiagnosticBuilder::<'a, G>::set_arg` - --> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:539:19 + --> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:569:19 | LL | arg: impl IntoDiagnosticArg, | ^^^^^^^^^^^^^^^^^ required by this bound in `DiagnosticBuilder::<'a, G>::set_arg` = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 48 previous errors +error: aborting due to 55 previous errors Some errors have detailed explanations: E0277, E0425. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/associated-types/associated-types-eq-3.stderr b/src/test/ui/associated-types/associated-types-eq-3.stderr index 19750fe1f333f..fbe1a1ee8bcd7 100644 --- a/src/test/ui/associated-types/associated-types-eq-3.stderr +++ b/src/test/ui/associated-types/associated-types-eq-3.stderr @@ -36,9 +36,7 @@ error[E0271]: type mismatch resolving `::A == Bar` --> $DIR/associated-types-eq-3.rs:40:9 | LL | baz(&a); - | --- ^^ type mismatch resolving `::A == Bar` - | | - | required by a bound introduced by this call + | ^^ type mismatch resolving `::A == Bar` | note: expected this to be `Bar` --> $DIR/associated-types-eq-3.rs:12:14 diff --git a/src/test/ui/associated-types/associated-types-path-2.stderr b/src/test/ui/associated-types/associated-types-path-2.stderr index 66f1ab726922d..5edd5c864e135 100644 --- a/src/test/ui/associated-types/associated-types-path-2.stderr +++ b/src/test/ui/associated-types/associated-types-path-2.stderr @@ -17,10 +17,12 @@ LL | f1(2i32, 4u32); | ~~~ error[E0277]: the trait bound `u32: Foo` is not satisfied - --> $DIR/associated-types-path-2.rs:29:5 + --> $DIR/associated-types-path-2.rs:29:8 | LL | f1(2u32, 4u32); - | ^^ the trait `Foo` is not implemented for `u32` + | -- ^^^^ the trait `Foo` is not implemented for `u32` + | | + | required by a bound introduced by this call | = help: the trait `Foo` is implemented for `i32` note: required by a bound in `f1` @@ -33,9 +35,7 @@ error[E0277]: the trait bound `u32: Foo` is not satisfied --> $DIR/associated-types-path-2.rs:29:14 | LL | f1(2u32, 4u32); - | -- ^^^^ the trait `Foo` is not implemented for `u32` - | | - | required by a bound introduced by this call + | ^^^^ the trait `Foo` is not implemented for `u32` | = help: the trait `Foo` is implemented for `i32` diff --git a/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr b/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr index 22daaf329102a..a14a273b3ece9 100644 --- a/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr +++ b/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr @@ -1,10 +1,8 @@ error[E0277]: the trait bound `T: Copy` is not satisfied - --> $DIR/issue-27675-unchecked-bounds.rs:15:31 + --> $DIR/issue-27675-unchecked-bounds.rs:15:12 | LL | copy::>(t) - | ------------------------- ^ the trait `Copy` is not implemented for `T` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T` | note: required by a bound in `copy` --> $DIR/issue-27675-unchecked-bounds.rs:10:12 diff --git a/src/test/ui/async-await/issue-67252-unnamed-future.stderr b/src/test/ui/async-await/issue-67252-unnamed-future.stderr index 01c0d3225ba0b..af99b608ca14d 100644 --- a/src/test/ui/async-await/issue-67252-unnamed-future.stderr +++ b/src/test/ui/async-await/issue-67252-unnamed-future.stderr @@ -1,8 +1,12 @@ error: future cannot be sent between threads safely - --> $DIR/issue-67252-unnamed-future.rs:18:5 + --> $DIR/issue-67252-unnamed-future.rs:18:11 | -LL | spawn(async { - | ^^^^^ future created by async block is not `Send` +LL | spawn(async { + | ___________^ +LL | | let _a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send` +LL | | AFuture.await; +LL | | }); + | |_____^ future created by async block is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `*mut ()` note: future is not `Send` as this value is used across an await diff --git a/src/test/ui/async-await/issue-68112.stderr b/src/test/ui/async-await/issue-68112.stderr index 9c85eb8768497..c3553e3e0c1c2 100644 --- a/src/test/ui/async-await/issue-68112.stderr +++ b/src/test/ui/async-await/issue-68112.stderr @@ -1,8 +1,8 @@ error: future cannot be sent between threads safely - --> $DIR/issue-68112.rs:34:5 + --> $DIR/issue-68112.rs:34:18 | LL | require_send(send_fut); - | ^^^^^^^^^^^^ future created by async block is not `Send` + | ^^^^^^^^ future created by async block is not `Send` | = help: the trait `Sync` is not implemented for `RefCell` note: future is not `Send` as it awaits another future which is not `Send` @@ -17,10 +17,10 @@ LL | fn require_send(_: impl Send) {} | ^^^^ required by this bound in `require_send` error: future cannot be sent between threads safely - --> $DIR/issue-68112.rs:43:5 + --> $DIR/issue-68112.rs:43:18 | LL | require_send(send_fut); - | ^^^^^^^^^^^^ future created by async block is not `Send` + | ^^^^^^^^ future created by async block is not `Send` | = help: the trait `Sync` is not implemented for `RefCell` note: future is not `Send` as it awaits another future which is not `Send` @@ -35,10 +35,12 @@ LL | fn require_send(_: impl Send) {} | ^^^^ required by this bound in `require_send` error[E0277]: `RefCell` cannot be shared between threads safely - --> $DIR/issue-68112.rs:60:5 + --> $DIR/issue-68112.rs:60:18 | LL | require_send(send_fut); - | ^^^^^^^^^^^^ `RefCell` cannot be shared between threads safely + | ------------ ^^^^^^^^ `RefCell` cannot be shared between threads safely + | | + | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `RefCell` = note: required for `Arc>` to implement `Send` diff --git a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr index b230930012914..99e960f5d0f26 100644 --- a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr +++ b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr @@ -1,8 +1,12 @@ error: future cannot be sent between threads safely - --> $DIR/issue-65436-raw-ptr-not-send.rs:12:5 + --> $DIR/issue-65436-raw-ptr-not-send.rs:12:17 | -LL | assert_send(async { - | ^^^^^^^^^^^ future created by async block is not `Send` +LL | assert_send(async { + | _________________^ +LL | | +LL | | bar(Foo(std::ptr::null())).await; +LL | | }) + | |_____^ future created by async block is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `*const u8` note: future is not `Send` as this value is used across an await diff --git a/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.stderr b/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.stderr index 7d6bf58f51696..0c4970a72591f 100644 --- a/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.stderr +++ b/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied in `(MyS2, MyS)` - --> $DIR/typeck-default-trait-impl-constituent-types-2.rs:17:5 + --> $DIR/typeck-default-trait-impl-constituent-types-2.rs:17:18 | LL | is_mytrait::<(MyS2, MyS)>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ within `(MyS2, MyS)`, the trait `MyTrait` is not implemented for `MyS2` + | ^^^^^^^^^^^ within `(MyS2, MyS)`, the trait `MyTrait` is not implemented for `MyS2` | = note: required because it appears within the type `(MyS2, MyS)` note: required by a bound in `is_mytrait` diff --git a/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr b/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr index 5645e15850274..ce7095664c11a 100644 --- a/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr +++ b/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `u32: Signed` is not satisfied - --> $DIR/typeck-default-trait-impl-precedence.rs:19:5 + --> $DIR/typeck-default-trait-impl-precedence.rs:19:20 | LL | is_defaulted::<&'static u32>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32` + | ^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32` | = help: the trait `Signed` is implemented for `i32` note: required for `&'static u32` to implement `Defaulted` diff --git a/src/test/ui/chalkify/type_wf.rs b/src/test/ui/chalkify/type_wf.rs index dd83a03fdf691..eeeefcfb7dd15 100644 --- a/src/test/ui/chalkify/type_wf.rs +++ b/src/test/ui/chalkify/type_wf.rs @@ -15,8 +15,8 @@ fn main() { x: 5, }; - let s = S { //~ ERROR the trait bound `{float}: Foo` is not satisfied - x: 5.0, + let s = S { + x: 5.0, //~ ERROR the trait bound `{float}: Foo` is not satisfied }; let s = S { diff --git a/src/test/ui/chalkify/type_wf.stderr b/src/test/ui/chalkify/type_wf.stderr index 7f8566082cd26..6e8daf635175f 100644 --- a/src/test/ui/chalkify/type_wf.stderr +++ b/src/test/ui/chalkify/type_wf.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `{float}: Foo` is not satisfied - --> $DIR/type_wf.rs:18:13 + --> $DIR/type_wf.rs:19:12 | -LL | let s = S { - | ^ the trait `Foo` is not implemented for `{float}` +LL | x: 5.0, + | ^^^ the trait `Foo` is not implemented for `{float}` | = help: the trait `Foo` is implemented for `i32` note: required by a bound in `S` diff --git a/src/test/ui/closure_context/issue-26046-fn-mut.stderr b/src/test/ui/closure_context/issue-26046-fn-mut.stderr index 74d3c4977ee65..f744b71c284b0 100644 --- a/src/test/ui/closure_context/issue-26046-fn-mut.stderr +++ b/src/test/ui/closure_context/issue-26046-fn-mut.stderr @@ -8,6 +8,8 @@ LL | num += 1; ... LL | Box::new(closure) | ----------------- the requirement to implement `Fn` derives from here + | + = note: required for the cast from `[closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21]` to the object type `dyn Fn()` error: aborting due to previous error diff --git a/src/test/ui/closure_context/issue-26046-fn-once.stderr b/src/test/ui/closure_context/issue-26046-fn-once.stderr index 473e8e8417e6e..34f94f9dca6d3 100644 --- a/src/test/ui/closure_context/issue-26046-fn-once.stderr +++ b/src/test/ui/closure_context/issue-26046-fn-once.stderr @@ -8,6 +8,8 @@ LL | vec ... LL | Box::new(closure) | ----------------- the requirement to implement `Fn` derives from here + | + = note: required for the cast from `[closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26]` to the object type `dyn Fn() -> Vec` error: aborting due to previous error diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr index bcde35983fc4c..309c63e52932b 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr @@ -7,7 +7,15 @@ LL | let [_, _s] = s; | - closure is `FnOnce` because it moves the variable `s` out of its environment LL | }; LL | expect_fn(c); - | --------- the requirement to implement `Fn` derives from here + | --------- - the requirement to implement `Fn` derives from here + | | + | required by a bound introduced by this call + | +note: required by a bound in `expect_fn` + --> $DIR/closure-origin-array-diagnostics.rs:5:17 + | +LL | fn expect_fn(_f: F) {} + | ^^^^ required by this bound in `expect_fn` error: aborting due to previous error diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr index df33c4f1fd6d4..3e77635f9e0c8 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr @@ -7,7 +7,15 @@ LL | let s = s.1; | --- closure is `FnOnce` because it moves the variable `s.1` out of its environment LL | }; LL | expect_fn(c); - | --------- the requirement to implement `Fn` derives from here + | --------- - the requirement to implement `Fn` derives from here + | | + | required by a bound introduced by this call + | +note: required by a bound in `expect_fn` + --> $DIR/closure-origin-tuple-diagnostics.rs:5:17 + | +LL | fn expect_fn(_f: F) {} + | ^^^^ required by this bound in `expect_fn` error: aborting due to previous error diff --git a/src/test/ui/closures/closure-move-sync.stderr b/src/test/ui/closures/closure-move-sync.stderr index 3e9b1c292dc18..a2ca06b4e6e1a 100644 --- a/src/test/ui/closures/closure-move-sync.stderr +++ b/src/test/ui/closures/closure-move-sync.stderr @@ -1,8 +1,14 @@ error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely - --> $DIR/closure-move-sync.rs:6:13 + --> $DIR/closure-move-sync.rs:6:27 | -LL | let t = thread::spawn(|| { - | ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely +LL | let t = thread::spawn(|| { + | _____________-------------_^ + | | | + | | required by a bound introduced by this call +LL | | recv.recv().unwrap(); +LL | | +LL | | }); + | |_____^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<()>` = note: required for `&std::sync::mpsc::Receiver<()>` to implement `Send` @@ -18,10 +24,12 @@ LL | F: Send + 'static, | ^^^^ required by this bound in `spawn` error[E0277]: `Sender<()>` cannot be shared between threads safely - --> $DIR/closure-move-sync.rs:18:5 + --> $DIR/closure-move-sync.rs:18:19 | LL | thread::spawn(|| tx.send(()).unwrap()); - | ^^^^^^^^^^^^^ `Sender<()>` cannot be shared between threads safely + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^ `Sender<()>` cannot be shared between threads safely + | | + | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `Sender<()>` = note: required for `&Sender<()>` to implement `Send` diff --git a/src/test/ui/closures/closure-wrong-kind.stderr b/src/test/ui/closures/closure-wrong-kind.stderr index 35caf71a5e8c7..9ea55d764f345 100644 --- a/src/test/ui/closures/closure-wrong-kind.stderr +++ b/src/test/ui/closures/closure-wrong-kind.stderr @@ -6,7 +6,15 @@ LL | let closure = |_| foo(x); | | | this closure implements `FnOnce`, not `Fn` LL | bar(closure); - | --- the requirement to implement `Fn` derives from here + | --- ------- the requirement to implement `Fn` derives from here + | | + | required by a bound introduced by this call + | +note: required by a bound in `bar` + --> $DIR/closure-wrong-kind.rs:6:11 + | +LL | fn bar(_: T) {} + | ^^^^^^^ required by this bound in `bar` error: aborting due to previous error diff --git a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr index a9c185e5fcbd1..0e8334d033820 100644 --- a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr +++ b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr @@ -2,9 +2,7 @@ error[E0277]: the trait bound `u32: Trait` is not satisfied --> $DIR/trait_objects_fail.rs:26:9 | LL | foo(&10_u32); - | --- ^^^^^^^ the trait `Trait` is not implemented for `u32` - | | - | required by a bound introduced by this call + | ^^^^^^^ the trait `Trait` is not implemented for `u32` | = help: the trait `Trait<2>` is implemented for `u32` = note: required for the cast from `u32` to the object type `dyn Trait` @@ -13,9 +11,7 @@ error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied --> $DIR/trait_objects_fail.rs:28:9 | LL | bar(&true); - | --- ^^^^^ the trait `Traitor<_>` is not implemented for `bool` - | | - | required by a bound introduced by this call + | ^^^^^ the trait `Traitor<_>` is not implemented for `bool` | = help: the trait `Traitor<2, 3>` is implemented for `bool` = note: required for the cast from `bool` to the object type `dyn Traitor<_>` diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr index a5f7bc0b26cbd..615dc875f67a3 100644 --- a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr @@ -1,8 +1,8 @@ error: unconstrained generic constant - --> $DIR/abstract-const-as-cast-3.rs:17:5 + --> $DIR/abstract-const-as-cast-3.rs:17:19 | LL | assert_impl::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:` note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait` @@ -26,10 +26,10 @@ LL | assert_impl::>(); found type `{ O as u128 }` error: unconstrained generic constant - --> $DIR/abstract-const-as-cast-3.rs:20:5 + --> $DIR/abstract-const-as-cast-3.rs:20:19 | LL | assert_impl::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:` note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait` @@ -71,10 +71,10 @@ LL | assert_impl::>(); found type `14` error: unconstrained generic constant - --> $DIR/abstract-const-as-cast-3.rs:35:5 + --> $DIR/abstract-const-as-cast-3.rs:35:19 | LL | assert_impl::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:` note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait` @@ -98,10 +98,10 @@ LL | assert_impl::>(); found type `{ O as u128 }` error: unconstrained generic constant - --> $DIR/abstract-const-as-cast-3.rs:38:5 + --> $DIR/abstract-const-as-cast-3.rs:38:19 | LL | assert_impl::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:` note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait` diff --git a/src/test/ui/consts/const-block-const-bound.stderr b/src/test/ui/consts/const-block-const-bound.stderr index 87ca771e54ed4..b9c4d8866bf9d 100644 --- a/src/test/ui/consts/const-block-const-bound.stderr +++ b/src/test/ui/consts/const-block-const-bound.stderr @@ -2,7 +2,7 @@ error[E0277]: can't drop `UnconstDrop` in const contexts --> $DIR/const-block-const-bound.rs:20:11 | LL | f(UnconstDrop); - | - ^^^^^^^^^^^ expected an implementor of trait `~const Destruct` + | - ^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `UnconstDrop` | | | required by a bound introduced by this call | @@ -23,7 +23,7 @@ error[E0277]: can't drop `NonDrop` in const contexts --> $DIR/const-block-const-bound.rs:22:11 | LL | f(NonDrop); - | - ^^^^^^^ expected an implementor of trait `~const Destruct` + | - ^^^^^^^ the trait `~const Destruct` is not implemented for `NonDrop` | | | required by a bound introduced by this call | diff --git a/src/test/ui/derives/deriving-copyclone.stderr b/src/test/ui/derives/deriving-copyclone.stderr index da895098e4b8e..80e2dd7fedefd 100644 --- a/src/test/ui/derives/deriving-copyclone.stderr +++ b/src/test/ui/derives/deriving-copyclone.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `B: Copy` is not satisfied --> $DIR/deriving-copyclone.rs:31:13 | LL | is_copy(B { a: 1, b: C }); - | ------- ^^^^^^^^^^^^^^^^ expected an implementor of trait `Copy` + | ------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `B` | | | required by a bound introduced by this call | @@ -26,7 +26,7 @@ error[E0277]: the trait bound `B: Clone` is not satisfied --> $DIR/deriving-copyclone.rs:32:14 | LL | is_clone(B { a: 1, b: C }); - | -------- ^^^^^^^^^^^^^^^^ expected an implementor of trait `Clone` + | -------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `B` | | | required by a bound introduced by this call | @@ -50,7 +50,7 @@ error[E0277]: the trait bound `B: Copy` is not satisfied --> $DIR/deriving-copyclone.rs:35:13 | LL | is_copy(B { a: 1, b: D }); - | ------- ^^^^^^^^^^^^^^^^ expected an implementor of trait `Copy` + | ------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `B` | | | required by a bound introduced by this call | diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr index 26764bc0ee5cc..b69fcd5d32a60 100644 --- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr +++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `Bar: Foo` is not satisfied - --> $DIR/issue-21659-show-relevant-trait-impls-1.rs:24:8 + --> $DIR/issue-21659-show-relevant-trait-impls-1.rs:24:12 | LL | f1.foo(1usize); - | ^^^ the trait `Foo` is not implemented for `Bar` + | --- ^^^^^^ the trait `Foo` is not implemented for `Bar` + | | + | required by a bound introduced by this call | = help: the following other types implement trait `Foo
`: > diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr index bb175367e1f9e..5e0e4a0115a0e 100644 --- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr +++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `Bar: Foo` is not satisfied - --> $DIR/issue-21659-show-relevant-trait-impls-2.rs:28:8 + --> $DIR/issue-21659-show-relevant-trait-impls-2.rs:28:12 | LL | f1.foo(1usize); - | ^^^ the trait `Foo` is not implemented for `Bar` + | --- ^^^^^^ the trait `Foo` is not implemented for `Bar` + | | + | required by a bound introduced by this call | = help: the following other types implement trait `Foo`: > diff --git a/src/test/ui/error-codes/E0277-2.stderr b/src/test/ui/error-codes/E0277-2.stderr index ca2cb88424076..a2abf37931a4f 100644 --- a/src/test/ui/error-codes/E0277-2.stderr +++ b/src/test/ui/error-codes/E0277-2.stderr @@ -1,8 +1,8 @@ error[E0277]: `*const u8` cannot be sent between threads safely - --> $DIR/E0277-2.rs:16:5 + --> $DIR/E0277-2.rs:16:15 | LL | is_send::(); - | ^^^^^^^^^^^^^^ `*const u8` cannot be sent between threads safely + | ^^^ `*const u8` cannot be sent between threads safely | = help: within `Foo`, the trait `Send` is not implemented for `*const u8` note: required because it appears within the type `Baz` diff --git a/src/test/ui/extern/extern-types-unsized.stderr b/src/test/ui/extern/extern-types-unsized.stderr index 8d6713261d5ec..a79caced111bb 100644 --- a/src/test/ui/extern/extern-types-unsized.stderr +++ b/src/test/ui/extern/extern-types-unsized.stderr @@ -16,10 +16,10 @@ LL | fn assert_sized() {} | ++++++++ error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/extern-types-unsized.rs:25:5 + --> $DIR/extern-types-unsized.rs:25:20 | LL | assert_sized::(); - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | = help: within `Foo`, the trait `Sized` is not implemented for `A` note: required because it appears within the type `Foo` @@ -38,10 +38,10 @@ LL | fn assert_sized() {} | ++++++++ error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/extern-types-unsized.rs:28:5 + --> $DIR/extern-types-unsized.rs:28:20 | LL | assert_sized::>(); - | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^ doesn't have a size known at compile-time | = help: within `Bar`, the trait `Sized` is not implemented for `A` note: required because it appears within the type `Bar` @@ -60,10 +60,10 @@ LL | fn assert_sized() {} | ++++++++ error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/extern-types-unsized.rs:31:5 + --> $DIR/extern-types-unsized.rs:31:20 | LL | assert_sized::>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^ doesn't have a size known at compile-time | = help: within `Bar>`, the trait `Sized` is not implemented for `A` note: required because it appears within the type `Bar` diff --git a/src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr b/src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr index 0557340f792fd..b7757740d9e34 100644 --- a/src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr +++ b/src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr @@ -15,9 +15,7 @@ error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known --> $DIR/feature-gate-unsized_fn_params.rs:24:9 | LL | foo(*x); - | --- ^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)` = help: unsized fn params are gated as an unstable feature diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr index 726d3e35b10e9..3ed040c3ab359 100644 --- a/src/test/ui/fmt/send-sync.stderr +++ b/src/test/ui/fmt/send-sync.stderr @@ -1,8 +1,10 @@ error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely - --> $DIR/send-sync.rs:8:5 + --> $DIR/send-sync.rs:8:10 | LL | send(format_args!("{:?}", c)); - | ^^^^ `core::fmt::Opaque` cannot be shared between threads safely + | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::Opaque` cannot be shared between threads safely + | | + | required by a bound introduced by this call | = help: within `[ArgumentV1<'_>]`, the trait `Sync` is not implemented for `core::fmt::Opaque` = note: required because it appears within the type `&core::fmt::Opaque` @@ -17,10 +19,12 @@ LL | fn send(_: T) {} | ^^^^ required by this bound in `send` error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely - --> $DIR/send-sync.rs:9:5 + --> $DIR/send-sync.rs:9:10 | LL | sync(format_args!("{:?}", c)); - | ^^^^ `core::fmt::Opaque` cannot be shared between threads safely + | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::Opaque` cannot be shared between threads safely + | | + | required by a bound introduced by this call | = help: within `Arguments<'_>`, the trait `Sync` is not implemented for `core::fmt::Opaque` = note: required because it appears within the type `&core::fmt::Opaque` diff --git a/src/test/ui/generator/drop-tracking-parent-expression.stderr b/src/test/ui/generator/drop-tracking-parent-expression.stderr index 522a300b3ed79..fbf5d6e07256b 100644 --- a/src/test/ui/generator/drop-tracking-parent-expression.stderr +++ b/src/test/ui/generator/drop-tracking-parent-expression.stderr @@ -1,8 +1,8 @@ error: generator cannot be sent between threads safely - --> $DIR/drop-tracking-parent-expression.rs:24:13 + --> $DIR/drop-tracking-parent-expression.rs:24:25 | LL | assert_send(g); - | ^^^^^^^^^^^ generator is not `Send` + | ^ generator is not `Send` ... LL | / type_combinations!( LL | | // OK @@ -41,10 +41,10 @@ LL | fn assert_send(_thing: T) {} = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: generator cannot be sent between threads safely - --> $DIR/drop-tracking-parent-expression.rs:24:13 + --> $DIR/drop-tracking-parent-expression.rs:24:25 | LL | assert_send(g); - | ^^^^^^^^^^^ generator is not `Send` + | ^ generator is not `Send` ... LL | / type_combinations!( LL | | // OK @@ -83,10 +83,10 @@ LL | fn assert_send(_thing: T) {} = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: generator cannot be sent between threads safely - --> $DIR/drop-tracking-parent-expression.rs:24:13 + --> $DIR/drop-tracking-parent-expression.rs:24:25 | LL | assert_send(g); - | ^^^^^^^^^^^ generator is not `Send` + | ^ generator is not `Send` ... LL | / type_combinations!( LL | | // OK diff --git a/src/test/ui/generator/drop-yield-twice.stderr b/src/test/ui/generator/drop-yield-twice.stderr index 5bc6ea5600fc5..0808a2c85ee1d 100644 --- a/src/test/ui/generator/drop-yield-twice.stderr +++ b/src/test/ui/generator/drop-yield-twice.stderr @@ -1,8 +1,14 @@ error: generator cannot be sent between threads safely - --> $DIR/drop-yield-twice.rs:7:5 + --> $DIR/drop-yield-twice.rs:7:17 | -LL | assert_send(|| { - | ^^^^^^^^^^^ generator is not `Send` +LL | assert_send(|| { + | _________________^ +LL | | let guard = Foo(42); +LL | | yield; +LL | | drop(guard); +LL | | yield; +LL | | }) + | |_____^ generator is not `Send` | = help: within `[generator@$DIR/drop-yield-twice.rs:7:17: 7:19]`, the trait `Send` is not implemented for `Foo` note: generator is not `Send` as this value is used across a yield diff --git a/src/test/ui/generator/generator-yielding-or-returning-itself.stderr b/src/test/ui/generator/generator-yielding-or-returning-itself.stderr index 2a39a08ee39b2..8f5d2429a2892 100644 --- a/src/test/ui/generator/generator-yielding-or-returning-itself.stderr +++ b/src/test/ui/generator/generator-yielding-or-returning-itself.stderr @@ -1,8 +1,15 @@ error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 15:36] as Generator>::Return == [generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 15:36]` - --> $DIR/generator-yielding-or-returning-itself.rs:15:5 + --> $DIR/generator-yielding-or-returning-itself.rs:15:34 | -LL | want_cyclic_generator_return(|| { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size +LL | want_cyclic_generator_return(|| { + | _____----------------------------_^ + | | | + | | required by a bound introduced by this call +LL | | +LL | | if false { yield None.unwrap(); } +LL | | None.unwrap() +LL | | }) + | |_____^ cyclic type of infinite size | = note: closures cannot capture themselves or take themselves as argument; this error may be the result of a recent compiler bug-fix, @@ -17,10 +24,17 @@ LL | where T: Generator | ^^^^^^^^^^ required by this bound in `want_cyclic_generator_return` error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 28:35] as Generator>::Yield == [generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 28:35]` - --> $DIR/generator-yielding-or-returning-itself.rs:28:5 + --> $DIR/generator-yielding-or-returning-itself.rs:28:33 | -LL | want_cyclic_generator_yield(|| { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size +LL | want_cyclic_generator_yield(|| { + | _____---------------------------_^ + | | | + | | required by a bound introduced by this call +LL | | +LL | | if false { yield None.unwrap(); } +LL | | None.unwrap() +LL | | }) + | |_____^ cyclic type of infinite size | = note: closures cannot capture themselves or take themselves as argument; this error may be the result of a recent compiler bug-fix, diff --git a/src/test/ui/generator/issue-68112.rs b/src/test/ui/generator/issue-68112.rs index 03b21c5ebd3ee..21026f45cb823 100644 --- a/src/test/ui/generator/issue-68112.rs +++ b/src/test/ui/generator/issue-68112.rs @@ -64,6 +64,7 @@ fn test2() { //~^ ERROR `RefCell` cannot be shared between threads safely //~| NOTE `RefCell` cannot be shared between threads safely //~| NOTE required for + //~| NOTE required by a bound introduced by this call //~| NOTE captures the following types } diff --git a/src/test/ui/generator/issue-68112.stderr b/src/test/ui/generator/issue-68112.stderr index b56f445872bc4..eb99d42c92068 100644 --- a/src/test/ui/generator/issue-68112.stderr +++ b/src/test/ui/generator/issue-68112.stderr @@ -1,8 +1,8 @@ error: generator cannot be sent between threads safely - --> $DIR/issue-68112.rs:40:5 + --> $DIR/issue-68112.rs:40:18 | LL | require_send(send_gen); - | ^^^^^^^^^^^^ generator is not `Send` + | ^^^^^^^^ generator is not `Send` | = help: the trait `Sync` is not implemented for `RefCell` note: generator is not `Send` as this value is used across a yield @@ -23,10 +23,12 @@ LL | fn require_send(_: impl Send) {} | ^^^^ required by this bound in `require_send` error[E0277]: `RefCell` cannot be shared between threads safely - --> $DIR/issue-68112.rs:63:5 + --> $DIR/issue-68112.rs:63:18 | LL | require_send(send_gen); - | ^^^^^^^^^^^^ `RefCell` cannot be shared between threads safely + | ------------ ^^^^^^^^ `RefCell` cannot be shared between threads safely + | | + | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `RefCell` = note: required for `Arc>` to implement `Send` diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr index b54b0f570c962..a821c57b923a0 100644 --- a/src/test/ui/generator/not-send-sync.stderr +++ b/src/test/ui/generator/not-send-sync.stderr @@ -1,8 +1,15 @@ error[E0277]: `Cell` cannot be shared between threads safely - --> $DIR/not-send-sync.rs:16:5 + --> $DIR/not-send-sync.rs:16:17 | -LL | assert_send(|| { - | ^^^^^^^^^^^ `Cell` cannot be shared between threads safely +LL | assert_send(|| { + | _____-----------_^ + | | | + | | required by a bound introduced by this call +LL | | +LL | | drop(&a); +LL | | yield; +LL | | }); + | |_____^ `Cell` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `Cell` = note: required for `&Cell` to implement `Send` @@ -18,10 +25,15 @@ LL | fn assert_send(_: T) {} | ^^^^ required by this bound in `assert_send` error: generator cannot be shared between threads safely - --> $DIR/not-send-sync.rs:9:5 - | -LL | assert_sync(|| { - | ^^^^^^^^^^^ generator is not `Sync` + --> $DIR/not-send-sync.rs:9:17 + | +LL | assert_sync(|| { + | _________________^ +LL | | +LL | | let a = Cell::new(2); +LL | | yield; +LL | | }); + | |_____^ generator is not `Sync` | = help: within `[generator@$DIR/not-send-sync.rs:9:17: 9:19]`, the trait `Sync` is not implemented for `Cell` note: generator is not `Sync` as this value is used across a yield diff --git a/src/test/ui/generator/partial-drop.stderr b/src/test/ui/generator/partial-drop.stderr index 1004fc64da93a..9baafe54e84d4 100644 --- a/src/test/ui/generator/partial-drop.stderr +++ b/src/test/ui/generator/partial-drop.stderr @@ -1,8 +1,15 @@ error: generator cannot be sent between threads safely - --> $DIR/partial-drop.rs:14:5 + --> $DIR/partial-drop.rs:14:17 | -LL | assert_send(|| { - | ^^^^^^^^^^^ generator is not `Send` +LL | assert_send(|| { + | _________________^ +LL | | +LL | | // FIXME: it would be nice to make this work. +LL | | let guard = Bar { foo: Foo, x: 42 }; +LL | | drop(guard.foo); +LL | | yield; +LL | | }); + | |_____^ generator is not `Send` | = help: within `[generator@$DIR/partial-drop.rs:14:17: 14:19]`, the trait `Send` is not implemented for `Foo` note: generator is not `Send` as this value is used across a yield @@ -22,10 +29,17 @@ LL | fn assert_send(_: T) {} | ^^^^ required by this bound in `assert_send` error: generator cannot be sent between threads safely - --> $DIR/partial-drop.rs:22:5 + --> $DIR/partial-drop.rs:22:17 | -LL | assert_send(|| { - | ^^^^^^^^^^^ generator is not `Send` +LL | assert_send(|| { + | _________________^ +LL | | +LL | | // FIXME: it would be nice to make this work. +LL | | let guard = Bar { foo: Foo, x: 42 }; +... | +LL | | yield; +LL | | }); + | |_____^ generator is not `Send` | = help: within `[generator@$DIR/partial-drop.rs:22:17: 22:19]`, the trait `Send` is not implemented for `Foo` note: generator is not `Send` as this value is used across a yield @@ -45,10 +59,17 @@ LL | fn assert_send(_: T) {} | ^^^^ required by this bound in `assert_send` error: generator cannot be sent between threads safely - --> $DIR/partial-drop.rs:32:5 + --> $DIR/partial-drop.rs:32:17 | -LL | assert_send(|| { - | ^^^^^^^^^^^ generator is not `Send` +LL | assert_send(|| { + | _________________^ +LL | | +LL | | // FIXME: it would be nice to make this work. +LL | | let guard = Bar { foo: Foo, x: 42 }; +... | +LL | | yield; +LL | | }); + | |_____^ generator is not `Send` | = help: within `[generator@$DIR/partial-drop.rs:32:17: 32:19]`, the trait `Send` is not implemented for `Foo` note: generator is not `Send` as this value is used across a yield diff --git a/src/test/ui/generator/print/generator-print-verbose-1.stderr b/src/test/ui/generator/print/generator-print-verbose-1.stderr index bbde8ea7892cc..3a83021dd9950 100644 --- a/src/test/ui/generator/print/generator-print-verbose-1.stderr +++ b/src/test/ui/generator/print/generator-print-verbose-1.stderr @@ -1,8 +1,8 @@ error: generator cannot be sent between threads safely - --> $DIR/generator-print-verbose-1.rs:37:5 + --> $DIR/generator-print-verbose-1.rs:37:18 | LL | require_send(send_gen); - | ^^^^^^^^^^^^ generator is not `Send` + | ^^^^^^^^ generator is not `Send` | = help: the trait `Sync` is not implemented for `RefCell` note: generator is not `Send` as this value is used across a yield @@ -21,10 +21,12 @@ LL | fn require_send(_: impl Send) {} | ^^^^ required by this bound in `require_send` error[E0277]: `RefCell` cannot be shared between threads safely - --> $DIR/generator-print-verbose-1.rs:56:5 + --> $DIR/generator-print-verbose-1.rs:56:18 | LL | require_send(send_gen); - | ^^^^^^^^^^^^ `RefCell` cannot be shared between threads safely + | ------------ ^^^^^^^^ `RefCell` cannot be shared between threads safely + | | + | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `RefCell` = note: required for `Arc>` to implement `Send` diff --git a/src/test/ui/generator/print/generator-print-verbose-2.stderr b/src/test/ui/generator/print/generator-print-verbose-2.stderr index 92ca51b4e7267..909e49c38b8d1 100644 --- a/src/test/ui/generator/print/generator-print-verbose-2.stderr +++ b/src/test/ui/generator/print/generator-print-verbose-2.stderr @@ -1,8 +1,15 @@ error[E0277]: `Cell` cannot be shared between threads safely - --> $DIR/generator-print-verbose-2.rs:19:5 + --> $DIR/generator-print-verbose-2.rs:19:17 | -LL | assert_send(|| { - | ^^^^^^^^^^^ `Cell` cannot be shared between threads safely +LL | assert_send(|| { + | _____-----------_^ + | | | + | | required by a bound introduced by this call +LL | | +LL | | drop(&a); +LL | | yield; +LL | | }); + | |_____^ `Cell` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `Cell` = note: required for `&'_#4r Cell` to implement `Send` @@ -18,10 +25,15 @@ LL | fn assert_send(_: T) {} | ^^^^ required by this bound in `assert_send` error: generator cannot be shared between threads safely - --> $DIR/generator-print-verbose-2.rs:12:5 - | -LL | assert_sync(|| { - | ^^^^^^^^^^^ generator is not `Sync` + --> $DIR/generator-print-verbose-2.rs:12:17 + | +LL | assert_sync(|| { + | _________________^ +LL | | +LL | | let a = Cell::new(2); +LL | | yield; +LL | | }); + | |_____^ generator is not `Sync` | = help: within `[main::{closure#0} upvar_tys=() {Cell, ()}]`, the trait `Sync` is not implemented for `Cell` note: generator is not `Sync` as this value is used across a yield diff --git a/src/test/ui/generic-associated-types/bugs/issue-88460.stderr b/src/test/ui/generic-associated-types/bugs/issue-88460.stderr index 98c304cc90b53..8193f491e69ed 100644 --- a/src/test/ui/generic-associated-types/bugs/issue-88460.stderr +++ b/src/test/ui/generic-associated-types/bugs/issue-88460.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `for<'a> <_ as Trait>::Assoc<'a>: Marker` is not satisfied - --> $DIR/issue-88460.rs:30:5 + --> $DIR/issue-88460.rs:30:10 | LL | test(Foo); - | ^^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>` + | ---- ^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>` + | | + | required by a bound introduced by this call | = help: the trait `Marker` is implemented for `()` note: required by a bound in `test` diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr index 066bf431a83d7..b30dd36d2ad6a 100644 --- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr @@ -1,8 +1,10 @@ error[E0277]: expected a `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F` - --> $DIR/issue-62529-3.rs:25:9 + --> $DIR/issue-62529-3.rs:25:14 | LL | call(f, ()); - | ^^^^ expected an `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F` + | ---- ^ expected an `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F` + | | + | required by a bound introduced by this call | = note: expected a closure with arguments `((),)` found a closure with arguments `(<_ as ATC<'a>>::Type,)` diff --git a/src/test/ui/inference/issue-71732.stderr b/src/test/ui/inference/issue-71732.stderr index 04673a375cf01..79bee33280d2e 100644 --- a/src/test/ui/inference/issue-71732.stderr +++ b/src/test/ui/inference/issue-71732.stderr @@ -2,7 +2,9 @@ error[E0283]: type annotations needed --> $DIR/issue-71732.rs:18:10 | LL | .get(&"key".into()) - | ^^^ cannot infer type of the type parameter `Q` declared on the associated function `get` + | ^^^ ------------- type must be known at this point + | | + | cannot infer type of the type parameter `Q` declared on the associated function `get` | = note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`: - impl Borrow for String; @@ -13,7 +15,7 @@ note: required by a bound in `HashMap::::get` | LL | K: Borrow, | ^^^^^^^^^ required by this bound in `HashMap::::get` -help: consider specifying the type argument in the function call +help: consider specifying the generic argument | LL | .get::(&"key".into()) | +++++ diff --git a/src/test/ui/inference/issue-86162-1.stderr b/src/test/ui/inference/issue-86162-1.stderr index e395e65fad066..4f621b82dc579 100644 --- a/src/test/ui/inference/issue-86162-1.stderr +++ b/src/test/ui/inference/issue-86162-1.stderr @@ -4,7 +4,7 @@ error[E0283]: type annotations needed LL | foo(gen()); //<- Do not suggest `foo::()`! | --- ^^^ cannot infer type of the type parameter `T` declared on the function `gen` | | - | type must be known at this point + | required by a bound introduced by this call | = note: cannot satisfy `_: Clone` note: required by a bound in `foo` diff --git a/src/test/ui/inference/issue-86162-2.stderr b/src/test/ui/inference/issue-86162-2.stderr index 30e6e10eaa2fd..9aff2cec160f2 100644 --- a/src/test/ui/inference/issue-86162-2.stderr +++ b/src/test/ui/inference/issue-86162-2.stderr @@ -4,7 +4,7 @@ error[E0283]: type annotations needed LL | Foo::bar(gen()); //<- Do not suggest `Foo::bar::()`! | -------- ^^^ cannot infer type of the type parameter `T` declared on the function `gen` | | - | type must be known at this point + | required by a bound introduced by this call | = note: cannot satisfy `_: Clone` note: required by a bound in `Foo::bar` diff --git a/src/test/ui/interior-mutability/interior-mutability.stderr b/src/test/ui/interior-mutability/interior-mutability.stderr index 7955fecda0670..94f41c9259886 100644 --- a/src/test/ui/interior-mutability/interior-mutability.stderr +++ b/src/test/ui/interior-mutability/interior-mutability.stderr @@ -1,8 +1,10 @@ error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/interior-mutability.rs:5:5 + --> $DIR/interior-mutability.rs:5:18 | LL | catch_unwind(|| { x.set(23); }); - | ^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ------------ ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | | + | required by a bound introduced by this call | = help: within `Cell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `Cell` diff --git a/src/test/ui/issues/issue-20162.stderr b/src/test/ui/issues/issue-20162.stderr index d70bf6e1d921c..3f9b3be985179 100644 --- a/src/test/ui/issues/issue-20162.stderr +++ b/src/test/ui/issues/issue-20162.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `X: Ord` is not satisfied - --> $DIR/issue-20162.rs:5:7 + --> $DIR/issue-20162.rs:5:5 | LL | b.sort(); - | ^^^^ the trait `Ord` is not implemented for `X` + | ^ ---- required by a bound introduced by this call + | | + | the trait `Ord` is not implemented for `X` | note: required by a bound in `slice::::sort` --> $SRC_DIR/alloc/src/slice.rs:LL:COL diff --git a/src/test/ui/issues/issue-20605.stderr b/src/test/ui/issues/issue-20605.stderr index b41b602a55b5c..e1858b6398932 100644 --- a/src/test/ui/issues/issue-20605.stderr +++ b/src/test/ui/issues/issue-20605.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `dyn Iterator` cann --> $DIR/issue-20605.rs:2:17 | LL | for item in *things { *item = 0 } - | ^^^^^^^ expected an implementor of trait `IntoIterator` + | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator` | = note: the trait bound `dyn Iterator: IntoIterator` is not satisfied = note: required for `dyn Iterator` to implement `IntoIterator` diff --git a/src/test/ui/issues/issue-21763.stderr b/src/test/ui/issues/issue-21763.stderr index 790681589248a..72c65029746ad 100644 --- a/src/test/ui/issues/issue-21763.stderr +++ b/src/test/ui/issues/issue-21763.stderr @@ -1,8 +1,8 @@ error[E0277]: `Rc<()>` cannot be sent between threads safely - --> $DIR/issue-21763.rs:9:5 + --> $DIR/issue-21763.rs:9:11 | LL | foo::, Rc<()>>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely + | ^^^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely | = help: within `(Rc<()>, Rc<()>)`, the trait `Send` is not implemented for `Rc<()>` = note: required because it appears within the type `(Rc<()>, Rc<()>)` diff --git a/src/test/ui/issues/issue-31173.rs b/src/test/ui/issues/issue-31173.rs index 472a95d4636bc..04efa27189b74 100644 --- a/src/test/ui/issues/issue-31173.rs +++ b/src/test/ui/issues/issue-31173.rs @@ -4,12 +4,12 @@ pub fn get_tok(it: &mut IntoIter) { let mut found_e = false; let temp: Vec = it + //~^ ERROR to be an iterator that yields `&_`, but it yields `u8` .take_while(|&x| { found_e = true; false }) .cloned() - //~^ ERROR to be an iterator that yields `&_`, but it yields `u8` .collect(); //~ ERROR the method } diff --git a/src/test/ui/issues/issue-31173.stderr b/src/test/ui/issues/issue-31173.stderr index 0b8222088b879..e3334eef3ad7f 100644 --- a/src/test/ui/issues/issue-31173.stderr +++ b/src/test/ui/issues/issue-31173.stderr @@ -1,8 +1,16 @@ -error[E0271]: expected `TakeWhile<&mut std::vec::IntoIter, [closure@$DIR/issue-31173.rs:7:21: 7:25]>` to be an iterator that yields `&_`, but it yields `u8` - --> $DIR/issue-31173.rs:11:10 - | -LL | .cloned() - | ^^^^^^ expected reference, found `u8` +error[E0271]: expected `TakeWhile<&mut std::vec::IntoIter, [closure@$DIR/issue-31173.rs:8:21: 8:25]>` to be an iterator that yields `&_`, but it yields `u8` + --> $DIR/issue-31173.rs:6:25 + | +LL | let temp: Vec = it + | _________________________^ +LL | | +LL | | .take_while(|&x| { +LL | | found_e = true; +LL | | false +LL | | }) + | |__________^ expected reference, found `u8` +LL | .cloned() + | ------ required by a bound introduced by this call | = note: expected reference `&_` found type `u8` @@ -12,11 +20,11 @@ note: required by a bound in `cloned` LL | Self: Sized + Iterator, | ^^^^^^^^^^^^ required by this bound in `cloned` -error[E0599]: the method `collect` exists for struct `Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>`, but its trait bounds were not satisfied +error[E0599]: the method `collect` exists for struct `Cloned, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>`, but its trait bounds were not satisfied --> $DIR/issue-31173.rs:13:10 | LL | .collect(); - | ^^^^^^^ method cannot be called on `Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>` due to unsatisfied trait bounds + | ^^^^^^^ method cannot be called on `Cloned, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>` due to unsatisfied trait bounds | ::: $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL | @@ -29,10 +37,10 @@ LL | pub struct Cloned { | -------------------- doesn't satisfy `_: Iterator` | = note: the following trait bounds were not satisfied: - `, [closure@$DIR/issue-31173.rs:7:21: 7:25]> as Iterator>::Item = &_` - which is required by `Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator` - `Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator` - which is required by `&mut Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator` + `, [closure@$DIR/issue-31173.rs:8:21: 8:25]> as Iterator>::Item = &_` + which is required by `Cloned, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator` + `Cloned, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator` + which is required by `&mut Cloned, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-33941.stderr b/src/test/ui/issues/issue-33941.stderr index caba0ad52689e..691b8f88f4ed5 100644 --- a/src/test/ui/issues/issue-33941.stderr +++ b/src/test/ui/issues/issue-33941.stderr @@ -1,8 +1,10 @@ error[E0271]: expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)` - --> $DIR/issue-33941.rs:6:36 + --> $DIR/issue-33941.rs:6:14 | LL | for _ in HashMap::new().iter().cloned() {} - | ^^^^^^ expected reference, found tuple + | ^^^^^^^^^^^^^^^^^^^^^ ------ required by a bound introduced by this call + | | + | expected reference, found tuple | = note: expected reference `&_` found tuple `(&_, &_)` diff --git a/src/test/ui/issues/issue-34334.stderr b/src/test/ui/issues/issue-34334.stderr index 48ae2df691c3d..72082f0cd1728 100644 --- a/src/test/ui/issues/issue-34334.stderr +++ b/src/test/ui/issues/issue-34334.stderr @@ -13,10 +13,12 @@ LL | let sr: Vec<(u32, _, _)> = vec![]; | + error[E0277]: a value of type `Vec<(u32, _, _)>` cannot be built from an iterator over elements of type `()` - --> $DIR/issue-34334.rs:5:87 + --> $DIR/issue-34334.rs:5:33 | LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect(); - | ^^^^^^^ value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call + | | + | value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>` = help: the trait `FromIterator` is implemented for `Vec` diff --git a/src/test/ui/issues/issue-34349.stderr b/src/test/ui/issues/issue-34349.stderr index d0b51961b44a7..8e9a16619f3b1 100644 --- a/src/test/ui/issues/issue-34349.stderr +++ b/src/test/ui/issues/issue-34349.stderr @@ -7,7 +7,15 @@ LL | farewell.push_str("!!!"); | -------- closure is `FnMut` because it mutates the variable `farewell` here ... LL | apply(diary); - | ----- the requirement to implement `Fn` derives from here + | ----- ----- the requirement to implement `Fn` derives from here + | | + | required by a bound introduced by this call + | +note: required by a bound in `apply` + --> $DIR/issue-34349.rs:11:32 + | +LL | fn apply(f: F) where F: Fn() { + | ^^^^ required by this bound in `apply` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-59488.rs b/src/test/ui/issues/issue-59488.rs index 922b593935aa8..384501e3e5dfd 100644 --- a/src/test/ui/issues/issue-59488.rs +++ b/src/test/ui/issues/issue-59488.rs @@ -30,4 +30,5 @@ fn main() { assert_eq!(Foo::Bar, i); //~^ ERROR binary operation `==` cannot be applied to type `fn(usize) -> Foo {Foo::Bar}` [E0369] //~| ERROR `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` [E0277] + //~| ERROR `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` [E0277] } diff --git a/src/test/ui/issues/issue-59488.stderr b/src/test/ui/issues/issue-59488.stderr index 7ce3dedaa887b..bb6843a19586e 100644 --- a/src/test/ui/issues/issue-59488.stderr +++ b/src/test/ui/issues/issue-59488.stderr @@ -106,7 +106,26 @@ LL | assert_eq!(Foo::Bar, i); and 68 others = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 9 previous errors +error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` + --> $DIR/issue-59488.rs:30:5 + | +LL | assert_eq!(Foo::Bar, i); + | ^^^^^^^^^^^^^^^^^^^^^^^ `fn(usize) -> Foo {Foo::Bar}` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = help: the trait `Debug` is not implemented for `fn(usize) -> Foo {Foo::Bar}` + = help: the following other types implement trait `Debug`: + extern "C" fn() -> Ret + extern "C" fn(A, B) -> Ret + extern "C" fn(A, B, ...) -> Ret + extern "C" fn(A, B, C) -> Ret + extern "C" fn(A, B, C, ...) -> Ret + extern "C" fn(A, B, C, D) -> Ret + extern "C" fn(A, B, C, D, ...) -> Ret + extern "C" fn(A, B, C, D, E) -> Ret + and 68 others + = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 10 previous errors Some errors have detailed explanations: E0277, E0308, E0369. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-60218.stderr b/src/test/ui/issues/issue-60218.stderr index 870b25014471d..dd72b6515ddca 100644 --- a/src/test/ui/issues/issue-60218.stderr +++ b/src/test/ui/issues/issue-60218.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `&u32: Foo` is not satisfied - --> $DIR/issue-60218.rs:18:27 + --> $DIR/issue-60218.rs:18:19 | LL | trigger_error(vec![], |x: &u32| x) - | ------------- ^^^^^^^^^^^ the trait `Foo` is not implemented for `&u32` + | ------------- ^^^^^^ the trait `Foo` is not implemented for `&u32` | | | required by a bound introduced by this call | diff --git a/src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr b/src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr index d6e39251632ba..2de1503765082 100644 --- a/src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr +++ b/src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr @@ -1,8 +1,10 @@ error[E0277]: a value of type `Vec` cannot be built from an iterator over elements of type `&f64` - --> $DIR/issue-66923-show-error-for-correct-call.rs:8:39 + --> $DIR/issue-66923-show-error-for-correct-call.rs:8:24 | LL | let x2: Vec = x1.into_iter().collect(); - | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` + | ^^^^^^^^^^^^^^ ------- required by a bound introduced by this call + | | + | value of type `Vec` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<&f64>` is not implemented for `Vec` = help: the trait `FromIterator` is implemented for `Vec` @@ -13,10 +15,12 @@ LL | fn collect>(self) -> B | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect` error[E0277]: a value of type `Vec` cannot be built from an iterator over elements of type `&f64` - --> $DIR/issue-66923-show-error-for-correct-call.rs:12:29 + --> $DIR/issue-66923-show-error-for-correct-call.rs:12:14 | LL | let x3 = x1.into_iter().collect::>(); - | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` + | ^^^^^^^^^^^^^^ ------- required by a bound introduced by this call + | | + | value of type `Vec` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<&f64>` is not implemented for `Vec` = help: the trait `FromIterator` is implemented for `Vec` diff --git a/src/test/ui/issues/issue-69455.stderr b/src/test/ui/issues/issue-69455.stderr index b732df764e57f..9d11cf19ea77c 100644 --- a/src/test/ui/issues/issue-69455.stderr +++ b/src/test/ui/issues/issue-69455.stderr @@ -16,7 +16,7 @@ error[E0283]: type annotations needed LL | println!("{}", 23u64.test(xs.iter().sum())); | ---- ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` | | - | type must be known at this point + | required by a bound introduced by this call | note: multiple `impl`s satisfying `u64: Test<_>` found --> $DIR/issue-69455.rs:11:1 diff --git a/src/test/ui/iterators/collect-into-array.rs b/src/test/ui/iterators/collect-into-array.rs index a1144c8cb8c6a..7d35da825328e 100644 --- a/src/test/ui/iterators/collect-into-array.rs +++ b/src/test/ui/iterators/collect-into-array.rs @@ -4,4 +4,5 @@ fn main() { //~^ ERROR an array of type `[u32; 10]` cannot be built directly from an iterator //~| NOTE try collecting into a `Vec<{integer}>`, then using `.try_into()` //~| NOTE required by a bound in `collect` + //~| NOTE required by a bound introduced by this call } diff --git a/src/test/ui/iterators/collect-into-array.stderr b/src/test/ui/iterators/collect-into-array.stderr index 7be53a4873bcc..7fe9707e6d232 100644 --- a/src/test/ui/iterators/collect-into-array.stderr +++ b/src/test/ui/iterators/collect-into-array.stderr @@ -1,8 +1,10 @@ error[E0277]: an array of type `[u32; 10]` cannot be built directly from an iterator - --> $DIR/collect-into-array.rs:3:39 + --> $DIR/collect-into-array.rs:3:31 | LL | let whatever: [u32; 10] = (0..10).collect(); - | ^^^^^^^ try collecting into a `Vec<{integer}>`, then using `.try_into()` + | ^^^^^^^ ------- required by a bound introduced by this call + | | + | try collecting into a `Vec<{integer}>`, then using `.try_into()` | = help: the trait `FromIterator<{integer}>` is not implemented for `[u32; 10]` note: required by a bound in `collect` diff --git a/src/test/ui/iterators/collect-into-slice.rs b/src/test/ui/iterators/collect-into-slice.rs index aafa6bc8b9514..5eade075613fe 100644 --- a/src/test/ui/iterators/collect-into-slice.rs +++ b/src/test/ui/iterators/collect-into-slice.rs @@ -1,15 +1,20 @@ fn process_slice(data: &[i32]) { //~^ NOTE required by a bound in this + //~| NOTE required by a bound in this todo!() } fn main() { let some_generated_vec = (0..10).collect(); //~^ ERROR the size for values of type `[i32]` cannot be known at compilation time + //~| ERROR the size for values of type `[i32]` cannot be known at compilation time //~| ERROR a slice of type `[i32]` cannot be built since `[i32]` has no definite size //~| NOTE try explicitly collecting into a `Vec<{integer}>` //~| NOTE required by a bound in `collect` + //~| NOTE required by a bound in `collect` //~| NOTE all local variables must have a statically known size //~| NOTE doesn't have a size known at compile-time + //~| NOTE doesn't have a size known at compile-time + //~| NOTE required by a bound introduced by this call process_slice(&some_generated_vec); } diff --git a/src/test/ui/iterators/collect-into-slice.stderr b/src/test/ui/iterators/collect-into-slice.stderr index 4842e65fe976b..bce40118bdfa0 100644 --- a/src/test/ui/iterators/collect-into-slice.stderr +++ b/src/test/ui/iterators/collect-into-slice.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `[i32]` cannot be known at compilation time - --> $DIR/collect-into-slice.rs:7:9 + --> $DIR/collect-into-slice.rs:8:9 | LL | let some_generated_vec = (0..10).collect(); | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -8,11 +8,26 @@ LL | let some_generated_vec = (0..10).collect(); = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature +error[E0277]: the size for values of type `[i32]` cannot be known at compilation time + --> $DIR/collect-into-slice.rs:8:38 + | +LL | let some_generated_vec = (0..10).collect(); + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[i32]` +note: required by a bound in `collect` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | +LL | fn collect>(self) -> B + | ^ required by this bound in `collect` + error[E0277]: a slice of type `[i32]` cannot be built since `[i32]` has no definite size - --> $DIR/collect-into-slice.rs:7:38 + --> $DIR/collect-into-slice.rs:8:30 | LL | let some_generated_vec = (0..10).collect(); - | ^^^^^^^ try explicitly collecting into a `Vec<{integer}>` + | ^^^^^^^ ------- required by a bound introduced by this call + | | + | try explicitly collecting into a `Vec<{integer}>` | = help: the trait `FromIterator<{integer}>` is not implemented for `[i32]` note: required by a bound in `collect` @@ -21,6 +36,6 @@ note: required by a bound in `collect` LL | fn collect>(self) -> B | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/kindck/kindck-impl-type-params-2.rs b/src/test/ui/kindck/kindck-impl-type-params-2.rs index 8b0771985dc3f..8950fc51e643c 100644 --- a/src/test/ui/kindck/kindck-impl-type-params-2.rs +++ b/src/test/ui/kindck/kindck-impl-type-params-2.rs @@ -11,5 +11,5 @@ fn take_param(foo: &T) { } fn main() { let x: Box<_> = Box::new(3); take_param(&x); - //~^ ERROR the trait bound `Box<{integer}>: Foo` is not satisfied + //~^ ERROR the trait bound `Box<{integer}>: Copy` is not satisfied } diff --git a/src/test/ui/kindck/kindck-impl-type-params-2.stderr b/src/test/ui/kindck/kindck-impl-type-params-2.stderr index 06d48ff1f0f27..930d96375bff4 100644 --- a/src/test/ui/kindck/kindck-impl-type-params-2.stderr +++ b/src/test/ui/kindck/kindck-impl-type-params-2.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied +error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied --> $DIR/kindck-impl-type-params-2.rs:13:16 | LL | take_param(&x); diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr index 09661289a9b77..e81d2441e6ef8 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied +error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied --> $DIR/kindck-inherited-copy-bound.rs:21:16 | LL | take_param(&x); diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr index 299600eb6bf30..2380533b9c3ef 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied +error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied --> $DIR/kindck-inherited-copy-bound.rs:21:16 | LL | take_param(&x); diff --git a/src/test/ui/kindck/kindck-nonsendable-1.stderr b/src/test/ui/kindck/kindck-nonsendable-1.stderr index eab003a110782..cc6e1f59c7789 100644 --- a/src/test/ui/kindck/kindck-nonsendable-1.stderr +++ b/src/test/ui/kindck/kindck-nonsendable-1.stderr @@ -1,10 +1,12 @@ error[E0277]: `Rc` cannot be sent between threads safely - --> $DIR/kindck-nonsendable-1.rs:9:5 + --> $DIR/kindck-nonsendable-1.rs:9:9 | LL | bar(move|| foo(x)); - | ^^^ ------ within this `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15]` - | | - | `Rc` cannot be sent between threads safely + | --- ------^^^^^^^ + | | | + | | `Rc` cannot be sent between threads safely + | | within this `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15]` + | required by a bound introduced by this call | = help: within `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15]`, the trait `Send` is not implemented for `Rc` note: required because it's used within this closure diff --git a/src/test/ui/kindck/kindck-send-object.stderr b/src/test/ui/kindck/kindck-send-object.stderr index 47b7462a6a104..e9bbeeacd7013 100644 --- a/src/test/ui/kindck/kindck-send-object.stderr +++ b/src/test/ui/kindck/kindck-send-object.stderr @@ -1,8 +1,8 @@ error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely - --> $DIR/kindck-send-object.rs:12:5 + --> $DIR/kindck-send-object.rs:12:19 | LL | assert_send::<&'static (dyn Dummy + 'static)>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)` = note: required for `&'static (dyn Dummy + 'static)` to implement `Send` @@ -13,10 +13,10 @@ LL | fn assert_send() { } | ^^^^ required by this bound in `assert_send` error[E0277]: `dyn Dummy` cannot be sent between threads safely - --> $DIR/kindck-send-object.rs:17:5 + --> $DIR/kindck-send-object.rs:17:19 | LL | assert_send::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely + | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `dyn Dummy` = note: required for `Unique` to implement `Send` diff --git a/src/test/ui/kindck/kindck-send-object1.stderr b/src/test/ui/kindck/kindck-send-object1.stderr index 24428266cc717..11f597fee91be 100644 --- a/src/test/ui/kindck/kindck-send-object1.stderr +++ b/src/test/ui/kindck/kindck-send-object1.stderr @@ -1,8 +1,8 @@ error[E0277]: `(dyn Dummy + 'a)` cannot be shared between threads safely - --> $DIR/kindck-send-object1.rs:10:5 + --> $DIR/kindck-send-object1.rs:10:19 | LL | assert_send::<&'a dyn Dummy>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely + | ^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `(dyn Dummy + 'a)` = note: required for `&'a (dyn Dummy + 'a)` to implement `Send` @@ -13,10 +13,10 @@ LL | fn assert_send() { } | ^^^^ required by this bound in `assert_send` error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely - --> $DIR/kindck-send-object1.rs:28:5 + --> $DIR/kindck-send-object1.rs:28:19 | LL | assert_send::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely + | ^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `(dyn Dummy + 'a)` = note: required for `Unique<(dyn Dummy + 'a)>` to implement `Send` diff --git a/src/test/ui/kindck/kindck-send-object2.stderr b/src/test/ui/kindck/kindck-send-object2.stderr index 81ec65950d875..b8af33d0dc120 100644 --- a/src/test/ui/kindck/kindck-send-object2.stderr +++ b/src/test/ui/kindck/kindck-send-object2.stderr @@ -1,8 +1,8 @@ error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely - --> $DIR/kindck-send-object2.rs:7:5 + --> $DIR/kindck-send-object2.rs:7:19 | LL | assert_send::<&'static dyn Dummy>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely + | ^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)` = note: required for `&'static (dyn Dummy + 'static)` to implement `Send` @@ -13,10 +13,10 @@ LL | fn assert_send() { } | ^^^^ required by this bound in `assert_send` error[E0277]: `dyn Dummy` cannot be sent between threads safely - --> $DIR/kindck-send-object2.rs:12:5 + --> $DIR/kindck-send-object2.rs:12:19 | LL | assert_send::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely + | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `dyn Dummy` = note: required for `Unique` to implement `Send` diff --git a/src/test/ui/kindck/kindck-send-owned.stderr b/src/test/ui/kindck/kindck-send-owned.stderr index 076c42959826d..b03f56465cea0 100644 --- a/src/test/ui/kindck/kindck-send-owned.stderr +++ b/src/test/ui/kindck/kindck-send-owned.stderr @@ -1,8 +1,8 @@ error[E0277]: `*mut u8` cannot be sent between threads safely - --> $DIR/kindck-send-owned.rs:12:5 + --> $DIR/kindck-send-owned.rs:12:19 | LL | assert_send::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely + | ^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `*mut u8` = note: required for `Unique<*mut u8>` to implement `Send` diff --git a/src/test/ui/lazy-type-alias-impl-trait/branches.stderr b/src/test/ui/lazy-type-alias-impl-trait/branches.stderr index 6b87da0c040d5..33f82448dd2ac 100644 --- a/src/test/ui/lazy-type-alias-impl-trait/branches.stderr +++ b/src/test/ui/lazy-type-alias-impl-trait/branches.stderr @@ -1,8 +1,10 @@ error[E0277]: a value of type `Bar` cannot be built from an iterator over elements of type `_` - --> $DIR/branches.rs:19:28 + --> $DIR/branches.rs:19:9 | LL | std::iter::empty().collect() - | ^^^^^^^ value of type `Bar` cannot be built from `std::iter::Iterator` + | ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call + | | + | value of type `Bar` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<_>` is not implemented for `Bar` note: required by a bound in `collect` diff --git a/src/test/ui/lazy-type-alias-impl-trait/recursion4.stderr b/src/test/ui/lazy-type-alias-impl-trait/recursion4.stderr index 42a1f782d299d..57978edf2bf05 100644 --- a/src/test/ui/lazy-type-alias-impl-trait/recursion4.stderr +++ b/src/test/ui/lazy-type-alias-impl-trait/recursion4.stderr @@ -1,8 +1,10 @@ error[E0277]: a value of type `Foo` cannot be built from an iterator over elements of type `_` - --> $DIR/recursion4.rs:10:28 + --> $DIR/recursion4.rs:10:9 | LL | x = std::iter::empty().collect(); - | ^^^^^^^ value of type `Foo` cannot be built from `std::iter::Iterator` + | ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call + | | + | value of type `Foo` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<_>` is not implemented for `Foo` note: required by a bound in `collect` @@ -12,10 +14,12 @@ LL | fn collect>(self) -> B | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect` error[E0277]: a value of type `impl Debug` cannot be built from an iterator over elements of type `_` - --> $DIR/recursion4.rs:19:28 + --> $DIR/recursion4.rs:19:9 | LL | x = std::iter::empty().collect(); - | ^^^^^^^ value of type `impl Debug` cannot be built from `std::iter::Iterator` + | ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call + | | + | value of type `impl Debug` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<_>` is not implemented for `impl Debug` note: required by a bound in `collect` diff --git a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr index c2515c40b1d77..36748fae13c94 100644 --- a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr +++ b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr @@ -1,8 +1,10 @@ error[E0277]: `Foo` doesn't implement `Debug` - --> $DIR/method-help-unsatisfied-bound.rs:5:7 + --> $DIR/method-help-unsatisfied-bound.rs:5:5 | LL | a.unwrap(); - | ^^^^^^ `Foo` cannot be formatted using `{:?}` + | ^ ------ required by a bound introduced by this call + | | + | `Foo` cannot be formatted using `{:?}` | = help: the trait `Debug` is not implemented for `Foo` = note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo` diff --git a/src/test/ui/never_type/defaulted-never-note.fallback.stderr b/src/test/ui/never_type/defaulted-never-note.fallback.stderr index 4c8b492247352..283aca1b084ef 100644 --- a/src/test/ui/never_type/defaulted-never-note.fallback.stderr +++ b/src/test/ui/never_type/defaulted-never-note.fallback.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied - --> $DIR/defaulted-never-note.rs:30:5 + --> $DIR/defaulted-never-note.rs:30:9 | LL | foo(_x); - | ^^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!` + | --- ^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!` + | | + | required by a bound introduced by this call | = help: the trait `ImplementedForUnitButNotNever` is implemented for `()` = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information) diff --git a/src/test/ui/never_type/defaulted-never-note.rs b/src/test/ui/never_type/defaulted-never-note.rs index aefc739a0a0b0..d30ffcd3846e7 100644 --- a/src/test/ui/never_type/defaulted-never-note.rs +++ b/src/test/ui/never_type/defaulted-never-note.rs @@ -32,6 +32,7 @@ fn smeg() { //[fallback]~| NOTE the trait `ImplementedForUnitButNotNever` is not implemented //[fallback]~| HELP trait `ImplementedForUnitButNotNever` is implemented for `()` //[fallback]~| NOTE this error might have been caused + //[fallback]~| NOTE required by a bound introduced by this call //[fallback]~| HELP did you intend } diff --git a/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr b/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr index dee2b1d704b86..3215c4669d5e3 100644 --- a/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr +++ b/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `!: Test` is not satisfied - --> $DIR/diverging-fallback-no-leak.rs:17:5 + --> $DIR/diverging-fallback-no-leak.rs:17:23 | LL | unconstrained_arg(return); - | ^^^^^^^^^^^^^^^^^ the trait `Test` is not implemented for `!` + | ----------------- ^^^^^^ the trait `Test` is not implemented for `!` + | | + | required by a bound introduced by this call | = help: the following other types implement trait `Test`: () diff --git a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr index 54abed383000d..6dc039fc35db7 100644 --- a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr +++ b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr @@ -1,8 +1,12 @@ error[E0277]: the trait bound `(): T` is not satisfied - --> $DIR/feature-gate-never_type_fallback.rs:10:5 + --> $DIR/feature-gate-never_type_fallback.rs:10:9 | LL | foo(panic!()) - | ^^^ the trait `T` is not implemented for `()` + | --- ^^^^^^^^ + | | | + | | the trait `T` is not implemented for `()` + | | this tail expression is of type `_` + | required by a bound introduced by this call | note: required by a bound in `foo` --> $DIR/feature-gate-never_type_fallback.rs:13:16 diff --git a/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr b/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr index e2045591390e1..06e902bca70fe 100644 --- a/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr +++ b/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `E: From<()>` is not satisfied - --> $DIR/never-value-fallback-issue-66757.rs:28:5 + --> $DIR/never-value-fallback-issue-66757.rs:28:26 | LL | >::from(never); - | ^^^^^^^^^^^^^^^^^^^^ the trait `From<()>` is not implemented for `E` + | -------------------- ^^^^^ the trait `From<()>` is not implemented for `E` + | | + | required by a bound introduced by this call | = help: the trait `From` is implemented for `E` diff --git a/src/test/ui/no-send-res-ports.stderr b/src/test/ui/no-send-res-ports.stderr index 249c2fe2fa74e..c864b93dbbbe1 100644 --- a/src/test/ui/no-send-res-ports.stderr +++ b/src/test/ui/no-send-res-ports.stderr @@ -1,10 +1,17 @@ error[E0277]: `Rc<()>` cannot be sent between threads safely - --> $DIR/no-send-res-ports.rs:25:5 + --> $DIR/no-send-res-ports.rs:25:19 | -LL | thread::spawn(move|| { - | ^^^^^^^^^^^^^ ------ within this `[closure@$DIR/no-send-res-ports.rs:25:19: 25:25]` - | | - | `Rc<()>` cannot be sent between threads safely +LL | thread::spawn(move|| { + | ------------- ^----- + | | | + | _____|_____________within this `[closure@$DIR/no-send-res-ports.rs:25:19: 25:25]` + | | | + | | required by a bound introduced by this call +LL | | +LL | | let y = x; +LL | | println!("{:?}", y); +LL | | }); + | |_____^ `Rc<()>` cannot be sent between threads safely | = help: within `[closure@$DIR/no-send-res-ports.rs:25:19: 25:25]`, the trait `Send` is not implemented for `Rc<()>` note: required because it appears within the type `Port<()>` diff --git a/src/test/ui/not-clone-closure.stderr b/src/test/ui/not-clone-closure.stderr index 37d94cf0ebd8c..f61ee661bb7ed 100644 --- a/src/test/ui/not-clone-closure.stderr +++ b/src/test/ui/not-clone-closure.stderr @@ -1,11 +1,13 @@ error[E0277]: the trait bound `S: Clone` is not satisfied in `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]` - --> $DIR/not-clone-closure.rs:11:23 + --> $DIR/not-clone-closure.rs:11:17 | LL | let hello = move || { | ------- within this `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]` ... LL | let hello = hello.clone(); - | ^^^^^ within `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`, the trait `Clone` is not implemented for `S` + | ^^^^^ ----- required by a bound introduced by this call + | | + | within `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`, the trait `Clone` is not implemented for `S` | note: required because it's used within this closure --> $DIR/not-clone-closure.rs:7:17 diff --git a/src/test/ui/not-panic/not-panic-safe-2.stderr b/src/test/ui/not-panic/not-panic-safe-2.stderr index 43bb31afa6f54..3b0f83b3b9a47 100644 --- a/src/test/ui/not-panic/not-panic-safe-2.stderr +++ b/src/test/ui/not-panic/not-panic-safe-2.stderr @@ -1,8 +1,8 @@ error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-2.rs:10:5 + --> $DIR/not-panic-safe-2.rs:10:14 | LL | assert::>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `RefCell` @@ -14,10 +14,10 @@ LL | fn assert() {} | ^^^^^^^^^^ required by this bound in `assert` error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-2.rs:10:5 + --> $DIR/not-panic-safe-2.rs:10:14 | LL | assert::>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `Cell` diff --git a/src/test/ui/not-panic/not-panic-safe-3.stderr b/src/test/ui/not-panic/not-panic-safe-3.stderr index ef1d1baf58bfc..9e9a12764a4b6 100644 --- a/src/test/ui/not-panic/not-panic-safe-3.stderr +++ b/src/test/ui/not-panic/not-panic-safe-3.stderr @@ -1,8 +1,8 @@ error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-3.rs:10:5 + --> $DIR/not-panic-safe-3.rs:10:14 | LL | assert::>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `RefCell` @@ -14,10 +14,10 @@ LL | fn assert() {} | ^^^^^^^^^^ required by this bound in `assert` error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-3.rs:10:5 + --> $DIR/not-panic-safe-3.rs:10:14 | LL | assert::>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `Cell` diff --git a/src/test/ui/not-panic/not-panic-safe-4.stderr b/src/test/ui/not-panic/not-panic-safe-4.stderr index a398b44d339e7..fc1c594d0d422 100644 --- a/src/test/ui/not-panic/not-panic-safe-4.stderr +++ b/src/test/ui/not-panic/not-panic-safe-4.stderr @@ -1,8 +1,8 @@ error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-4.rs:9:5 + --> $DIR/not-panic-safe-4.rs:9:14 | LL | assert::<&RefCell>(); - | ^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `RefCell` @@ -14,10 +14,10 @@ LL | fn assert() {} | ^^^^^^^^^^ required by this bound in `assert` error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-4.rs:9:5 + --> $DIR/not-panic-safe-4.rs:9:14 | LL | assert::<&RefCell>(); - | ^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `Cell` diff --git a/src/test/ui/not-panic/not-panic-safe-5.stderr b/src/test/ui/not-panic/not-panic-safe-5.stderr index 9617d5dfde40d..cb78370b48a6c 100644 --- a/src/test/ui/not-panic/not-panic-safe-5.stderr +++ b/src/test/ui/not-panic/not-panic-safe-5.stderr @@ -1,8 +1,8 @@ error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-5.rs:9:5 + --> $DIR/not-panic-safe-5.rs:9:14 | LL | assert::<*const UnsafeCell>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required for `*const UnsafeCell` to implement `UnwindSafe` diff --git a/src/test/ui/not-panic/not-panic-safe-6.stderr b/src/test/ui/not-panic/not-panic-safe-6.stderr index 09204d942d235..7986e341eb01f 100644 --- a/src/test/ui/not-panic/not-panic-safe-6.stderr +++ b/src/test/ui/not-panic/not-panic-safe-6.stderr @@ -1,8 +1,8 @@ error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-6.rs:9:5 + --> $DIR/not-panic-safe-6.rs:9:14 | LL | assert::<*mut RefCell>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `RefCell` @@ -14,10 +14,10 @@ LL | fn assert() {} | ^^^^^^^^^^ required by this bound in `assert` error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/not-panic-safe-6.rs:9:5 + --> $DIR/not-panic-safe-6.rs:9:14 | LL | assert::<*mut RefCell>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `Cell` diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr index 6e3601d7bf4b5..d47a398412fe4 100644 --- a/src/test/ui/on-unimplemented/multiple-impls.stderr +++ b/src/test/ui/on-unimplemented/multiple-impls.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `[i32]: Index` is not satisfied - --> $DIR/multiple-impls.rs:33:18 + --> $DIR/multiple-impls.rs:33:33 | LL | Index::index(&[] as &[i32], 2u32); - | ------------ ^^^^^^^^^^^^^ trait message + | ------------ ^^^^ trait message | | | required by a bound introduced by this call | @@ -12,10 +12,10 @@ LL | Index::index(&[] as &[i32], 2u32); <[i32] as Index>> error[E0277]: the trait bound `[i32]: Index>` is not satisfied - --> $DIR/multiple-impls.rs:35:18 + --> $DIR/multiple-impls.rs:35:33 | LL | Index::index(&[] as &[i32], Foo(2u32)); - | ------------ ^^^^^^^^^^^^^ on impl for Foo + | ------------ ^^^^^^^^^ on impl for Foo | | | required by a bound introduced by this call | @@ -25,10 +25,10 @@ LL | Index::index(&[] as &[i32], Foo(2u32)); <[i32] as Index>> error[E0277]: the trait bound `[i32]: Index>` is not satisfied - --> $DIR/multiple-impls.rs:37:18 + --> $DIR/multiple-impls.rs:37:33 | LL | Index::index(&[] as &[i32], Bar(2u32)); - | ------------ ^^^^^^^^^^^^^ on impl for Bar + | ------------ ^^^^^^^^^ on impl for Bar | | | required by a bound introduced by this call | diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr index 396c062cfe2ac..01315b854098e 100644 --- a/src/test/ui/on-unimplemented/on-impl.stderr +++ b/src/test/ui/on-unimplemented/on-impl.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `[i32]: Index` is not satisfied - --> $DIR/on-impl.rs:22:25 + --> $DIR/on-impl.rs:22:47 | LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); - | ------------------- ^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice + | ------------------- ^^^^ a usize is required to index into a slice | | | required by a bound introduced by this call | diff --git a/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr b/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr index 85c9fe409dbe9..a00f37ed6069c 100644 --- a/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr +++ b/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr @@ -107,10 +107,10 @@ LL | V = [Vec::new; { [0].len() ].len() as isize, | closing delimiter possibly meant for this error[E0282]: type annotations needed - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:29 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:26 | LL | V = [Vec::new; { [].len() ].len() as isize, - | ^^^ cannot infer type for type parameter `T` + | ^^ cannot infer type for type parameter `T` error[E0282]: type annotations needed --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:14 diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr index d96e863939c02..eba65a61803d0 100644 --- a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr @@ -8,7 +8,15 @@ LL | drop::(_x1); | --- closure is `FnOnce` because it moves the variable `_x1` out of its environment ... LL | accept_fn_mut(&c1); - | ------------- the requirement to implement `FnMut` derives from here + | ------------- --- the requirement to implement `FnMut` derives from here + | | + | required by a bound introduced by this call + | +note: required by a bound in `accept_fn_mut` + --> $DIR/move-ref-patterns-closure-captures.rs:4:31 + | +LL | fn accept_fn_mut(_: &impl FnMut()) {} + | ^^^^^^^ required by this bound in `accept_fn_mut` error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce` --> $DIR/move-ref-patterns-closure-captures.rs:9:14 @@ -20,7 +28,15 @@ LL | drop::(_x1); | --- closure is `FnOnce` because it moves the variable `_x1` out of its environment ... LL | accept_fn(&c1); - | --------- the requirement to implement `Fn` derives from here + | --------- --- the requirement to implement `Fn` derives from here + | | + | required by a bound introduced by this call + | +note: required by a bound in `accept_fn` + --> $DIR/move-ref-patterns-closure-captures.rs:5:27 + | +LL | fn accept_fn(_: &impl Fn()) {} + | ^^^^ required by this bound in `accept_fn` error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut` --> $DIR/move-ref-patterns-closure-captures.rs:20:14 @@ -32,7 +48,15 @@ LL | drop::<&mut U>(_x2); | --- closure is `FnMut` because it mutates the variable `_x2` here ... LL | accept_fn(&c2); - | --------- the requirement to implement `Fn` derives from here + | --------- --- the requirement to implement `Fn` derives from here + | | + | required by a bound introduced by this call + | +note: required by a bound in `accept_fn` + --> $DIR/move-ref-patterns-closure-captures.rs:5:27 + | +LL | fn accept_fn(_: &impl Fn()) {} + | ^^^^ required by this bound in `accept_fn` error: aborting due to 3 previous errors diff --git a/src/test/ui/proc-macro/signature.stderr b/src/test/ui/proc-macro/signature.stderr index a6bd98ddb1977..78b0beff0da39 100644 --- a/src/test/ui/proc-macro/signature.stderr +++ b/src/test/ui/proc-macro/signature.stderr @@ -5,7 +5,10 @@ LL | / pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { LL | | LL | | loop {} LL | | } - | |_^ call the function in a closure: `|| unsafe { /* code */ }` + | | ^ + | | | + | |_call the function in a closure: `|| unsafe { /* code */ }` + | required by a bound introduced by this call | = help: the trait `Fn<(proc_macro::TokenStream,)>` is not implemented for `unsafe extern "C" fn(i32, u32) -> u32 {foo}` = note: unsafe function cannot be called generically without an unsafe block diff --git a/src/test/ui/range/range-1.stderr b/src/test/ui/range/range-1.stderr index 0e3bb66ab61e9..aaea91ce0cbae 100644 --- a/src/test/ui/range/range-1.stderr +++ b/src/test/ui/range/range-1.stderr @@ -27,7 +27,7 @@ error[E0277]: the size for values of type `[{integer}]` cannot be known at compi --> $DIR/range-1.rs:14:17 | LL | let range = *arr..; - | ^^^^^^ doesn't have a size known at compile-time + | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[{integer}]` note: required by a bound in `RangeFrom` diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr index ec724cc9675f1..fddc8d37f2ff7 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr @@ -1,14 +1,16 @@ error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied - --> $DIR/const-default-method-bodies.rs:24:18 + --> $DIR/const-default-method-bodies.rs:24:5 | LL | NonConstImpl.a(); - | ^ the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl` + | ^^^^^^^^^^^^ - required by a bound introduced by this call + | | + | the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl` | note: the trait `ConstDefaultFn` is implemented for `NonConstImpl`, but that implementation is not `const` - --> $DIR/const-default-method-bodies.rs:24:18 + --> $DIR/const-default-method-bodies.rs:24:5 | LL | NonConstImpl.a(); - | ^ + | ^^^^^^^^^^^^ help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | LL | const fn test() where NonConstImpl: ~const ConstDefaultFn { diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr index ac61c3279217b..2295a822fa48b 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr @@ -5,7 +5,7 @@ LL | const _: () = check($exp); | ----- required by a bound introduced by this call ... LL | NonTrivialDrop, - | ^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct` + | ^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop` | = note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied note: required by a bound in `check` @@ -52,7 +52,7 @@ LL | const _: () = check($exp); | ----- required by a bound introduced by this call ... LL | ConstDropImplWithBounds::(PhantomData), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds` | note: required for `ConstDropImplWithBounds` to implement `~const Destruct` --> $DIR/const-drop-fail.rs:28:25 diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr index ac61c3279217b..2295a822fa48b 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr @@ -5,7 +5,7 @@ LL | const _: () = check($exp); | ----- required by a bound introduced by this call ... LL | NonTrivialDrop, - | ^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct` + | ^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop` | = note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied note: required by a bound in `check` @@ -52,7 +52,7 @@ LL | const _: () = check($exp); | ----- required by a bound introduced by this call ... LL | ConstDropImplWithBounds::(PhantomData), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds` | note: required for `ConstDropImplWithBounds` to implement `~const Destruct` --> $DIR/const-drop-fail.rs:28:25 diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr index 174c62912fcee..d4fa44b4bfcb5 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr @@ -1,14 +1,16 @@ error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied - --> $DIR/cross-crate.rs:17:14 + --> $DIR/cross-crate.rs:17:5 | LL | NonConst.func(); - | ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` + | ^^^^^^^^ ---- required by a bound introduced by this call + | | + | the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` | note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const` - --> $DIR/cross-crate.rs:17:14 + --> $DIR/cross-crate.rs:17:5 | LL | NonConst.func(); - | ^^^^ + | ^^^^^^^^ help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | LL | const fn const_context() where cross_crate::NonConst: ~const cross_crate::MyTrait { diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr index 4619dd1138e1f..71ecd9b06945f 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr @@ -1,14 +1,16 @@ error[E0277]: the trait bound `cross_crate::NonConst: cross_crate::MyTrait` is not satisfied - --> $DIR/cross-crate.rs:17:14 + --> $DIR/cross-crate.rs:17:5 | LL | NonConst.func(); - | ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` + | ^^^^^^^^ ---- required by a bound introduced by this call + | | + | the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` | note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const` - --> $DIR/cross-crate.rs:17:14 + --> $DIR/cross-crate.rs:17:5 | LL | NonConst.func(); - | ^^^^ + | ^^^^^^^^ help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | LL | const fn const_context() where cross_crate::NonConst: ~const cross_crate::MyTrait { diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr index b229053eb50cf..85285ba849777 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr @@ -1,14 +1,16 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied - --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12 + --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:9 | LL | ().a() - | ^ the trait `~const Tr` is not implemented for `()` + | ^^ - required by a bound introduced by this call + | | + | the trait `~const Tr` is not implemented for `()` | note: the trait `Tr` is implemented for `()`, but that implementation is not `const` - --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12 + --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:9 | LL | ().a() - | ^ + | ^^ help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | LL | pub trait Tr where (): ~const Tr { diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr index d5b2d26973096..fd5fe25ddcfb4 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr @@ -20,16 +20,16 @@ LL | const fn test1() { | ++++++++++++ error[E0277]: the trait bound `T: ~const Bar` is not satisfied - --> $DIR/trait-where-clause.rs:15:5 + --> $DIR/trait-where-clause.rs:15:12 | LL | T::c::(); - | ^^^^^^^^^ the trait `~const Bar` is not implemented for `T` + | ^ the trait `~const Bar` is not implemented for `T` | note: the trait `Bar` is implemented for `T`, but that implementation is not `const` - --> $DIR/trait-where-clause.rs:15:5 + --> $DIR/trait-where-clause.rs:15:12 | LL | T::c::(); - | ^^^^^^^^^ + | ^ note: required by a bound in `Foo::c` --> $DIR/trait-where-clause.rs:8:13 | @@ -57,10 +57,10 @@ LL | fn test3() { | +++++ error[E0277]: the trait bound `T: Bar` is not satisfied - --> $DIR/trait-where-clause.rs:29:5 + --> $DIR/trait-where-clause.rs:29:12 | LL | T::c::(); - | ^^^^^^^^^ the trait `Bar` is not implemented for `T` + | ^ the trait `Bar` is not implemented for `T` | note: required by a bound in `Foo::c` --> $DIR/trait-where-clause.rs:8:13 diff --git a/src/test/ui/stats/hir-stats.stderr b/src/test/ui/stats/hir-stats.stderr index 61cb7b25e4981..eb828bb9a2c17 100644 --- a/src/test/ui/stats/hir-stats.stderr +++ b/src/test/ui/stats/hir-stats.stderr @@ -4,58 +4,58 @@ PRE EXPANSION AST STATS Name Accumulated Size Count Item Size ---------------------------------------------------------------- ExprField 48 ( 0.6%) 1 48 -Attribute 64 ( 0.7%) 2 32 +Crate 56 ( 0.7%) 1 56 +Attribute 64 ( 0.8%) 2 32 - Normal 32 ( 0.4%) 1 - DocComment 32 ( 0.4%) 1 -GenericArgs 64 ( 0.7%) 1 64 -- AngleBracketed 64 ( 0.7%) 1 -Local 72 ( 0.8%) 1 72 -WherePredicate 72 ( 0.8%) 1 72 -- BoundPredicate 72 ( 0.8%) 1 -Crate 72 ( 0.8%) 1 72 +GenericArgs 64 ( 0.8%) 1 64 +- AngleBracketed 64 ( 0.8%) 1 +Local 72 ( 0.9%) 1 72 +WherePredicate 72 ( 0.9%) 1 72 +- BoundPredicate 72 ( 0.9%) 1 Arm 96 ( 1.1%) 2 48 -ForeignItem 112 ( 1.3%) 1 112 -- Fn 112 ( 1.3%) 1 -FieldDef 160 ( 1.8%) 2 80 -Stmt 160 ( 1.8%) 5 32 +ForeignItem 96 ( 1.1%) 1 96 +- Fn 96 ( 1.1%) 1 +FieldDef 160 ( 1.9%) 2 80 +Stmt 160 ( 1.9%) 5 32 - Local 32 ( 0.4%) 1 - MacCall 32 ( 0.4%) 1 - Expr 96 ( 1.1%) 3 -Param 160 ( 1.8%) 4 40 -FnDecl 200 ( 2.3%) 5 40 +Param 160 ( 1.9%) 4 40 +FnDecl 200 ( 2.4%) 5 40 Variant 240 ( 2.8%) 2 120 -Block 288 ( 3.3%) 6 48 -GenericBound 352 ( 4.0%) 4 88 -- Trait 352 ( 4.0%) 4 -AssocItem 480 ( 5.5%) 4 120 -- TyAlias 240 ( 2.8%) 2 -- Fn 240 ( 2.8%) 2 -GenericParam 520 ( 6.0%) 5 104 -PathSegment 720 ( 8.3%) 30 24 -Expr 832 ( 9.6%) 8 104 +Block 288 ( 3.4%) 6 48 +GenericBound 352 ( 4.2%) 4 88 +- Trait 352 ( 4.2%) 4 +AssocItem 416 ( 4.9%) 4 104 +- TyAlias 208 ( 2.5%) 2 +- Fn 208 ( 2.5%) 2 +GenericParam 520 ( 6.1%) 5 104 +PathSegment 720 ( 8.5%) 30 24 +Expr 832 ( 9.8%) 8 104 - Path 104 ( 1.2%) 1 - Match 104 ( 1.2%) 1 - Struct 104 ( 1.2%) 1 -- Lit 208 ( 2.4%) 2 -- Block 312 ( 3.6%) 3 -Pat 840 ( 9.7%) 7 120 +- Lit 208 ( 2.5%) 2 +- Block 312 ( 3.7%) 3 +Pat 840 ( 9.9%) 7 120 - Struct 120 ( 1.4%) 1 - Wild 120 ( 1.4%) 1 -- Ident 600 ( 6.9%) 5 -Ty 1_344 (15.5%) 14 96 +- Ident 600 ( 7.1%) 5 +Ty 1_344 (15.9%) 14 96 - Rptr 96 ( 1.1%) 1 - Ptr 96 ( 1.1%) 1 -- ImplicitSelf 192 ( 2.2%) 2 -- Path 960 (11.0%) 10 -Item 1_800 (20.7%) 9 200 -- Trait 200 ( 2.3%) 1 -- Enum 200 ( 2.3%) 1 -- ForeignMod 200 ( 2.3%) 1 -- Impl 200 ( 2.3%) 1 -- Fn 400 ( 4.6%) 2 -- Use 600 ( 6.9%) 3 +- ImplicitSelf 192 ( 2.3%) 2 +- Path 960 (11.4%) 10 +Item 1_656 (19.6%) 9 184 +- Trait 184 ( 2.2%) 1 +- Enum 184 ( 2.2%) 1 +- ForeignMod 184 ( 2.2%) 1 +- Impl 184 ( 2.2%) 1 +- Fn 368 ( 4.4%) 2 +- Use 552 ( 6.5%) 3 ---------------------------------------------------------------- -Total 8_696 +Total 8_456 POST EXPANSION AST STATS @@ -63,15 +63,15 @@ POST EXPANSION AST STATS Name Accumulated Size Count Item Size ---------------------------------------------------------------- ExprField 48 ( 0.5%) 1 48 +Crate 56 ( 0.6%) 1 56 GenericArgs 64 ( 0.7%) 1 64 - AngleBracketed 64 ( 0.7%) 1 Local 72 ( 0.8%) 1 72 WherePredicate 72 ( 0.8%) 1 72 - BoundPredicate 72 ( 0.8%) 1 -Crate 72 ( 0.8%) 1 72 Arm 96 ( 1.0%) 2 48 -ForeignItem 112 ( 1.2%) 1 112 -- Fn 112 ( 1.2%) 1 +ForeignItem 96 ( 1.0%) 1 96 +- Fn 96 ( 1.0%) 1 InlineAsm 120 ( 1.3%) 1 120 Attribute 128 ( 1.4%) 4 32 - DocComment 32 ( 0.3%) 1 @@ -82,42 +82,42 @@ Stmt 160 ( 1.7%) 5 32 - Semi 32 ( 0.3%) 1 - Expr 96 ( 1.0%) 3 Param 160 ( 1.7%) 4 40 -FnDecl 200 ( 2.1%) 5 40 -Variant 240 ( 2.5%) 2 120 -Block 288 ( 3.0%) 6 48 -GenericBound 352 ( 3.7%) 4 88 -- Trait 352 ( 3.7%) 4 -AssocItem 480 ( 5.1%) 4 120 -- TyAlias 240 ( 2.5%) 2 -- Fn 240 ( 2.5%) 2 -GenericParam 520 ( 5.5%) 5 104 -PathSegment 792 ( 8.4%) 33 24 -Pat 840 ( 8.9%) 7 120 +FnDecl 200 ( 2.2%) 5 40 +Variant 240 ( 2.6%) 2 120 +Block 288 ( 3.1%) 6 48 +GenericBound 352 ( 3.8%) 4 88 +- Trait 352 ( 3.8%) 4 +AssocItem 416 ( 4.5%) 4 104 +- TyAlias 208 ( 2.3%) 2 +- Fn 208 ( 2.3%) 2 +GenericParam 520 ( 5.7%) 5 104 +PathSegment 792 ( 8.6%) 33 24 +Pat 840 ( 9.1%) 7 120 - Struct 120 ( 1.3%) 1 - Wild 120 ( 1.3%) 1 -- Ident 600 ( 6.3%) 5 -Expr 936 ( 9.9%) 9 104 +- Ident 600 ( 6.5%) 5 +Expr 936 (10.2%) 9 104 - Path 104 ( 1.1%) 1 - Match 104 ( 1.1%) 1 - Struct 104 ( 1.1%) 1 - InlineAsm 104 ( 1.1%) 1 -- Lit 208 ( 2.2%) 2 -- Block 312 ( 3.3%) 3 -Ty 1_344 (14.2%) 14 96 +- Lit 208 ( 2.3%) 2 +- Block 312 ( 3.4%) 3 +Ty 1_344 (14.6%) 14 96 - Rptr 96 ( 1.0%) 1 - Ptr 96 ( 1.0%) 1 -- ImplicitSelf 192 ( 2.0%) 2 -- Path 960 (10.2%) 10 -Item 2_200 (23.3%) 11 200 -- Trait 200 ( 2.1%) 1 -- Enum 200 ( 2.1%) 1 -- ExternCrate 200 ( 2.1%) 1 -- ForeignMod 200 ( 2.1%) 1 -- Impl 200 ( 2.1%) 1 -- Fn 400 ( 4.2%) 2 -- Use 800 ( 8.5%) 4 +- ImplicitSelf 192 ( 2.1%) 2 +- Path 960 (10.5%) 10 +Item 2_024 (22.0%) 11 184 +- Trait 184 ( 2.0%) 1 +- Enum 184 ( 2.0%) 1 +- ExternCrate 184 ( 2.0%) 1 +- ForeignMod 184 ( 2.0%) 1 +- Impl 184 ( 2.0%) 1 +- Fn 368 ( 4.0%) 2 +- Use 736 ( 8.0%) 4 ---------------------------------------------------------------- -Total 9_456 +Total 9_184 HIR STATS diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr index 71facf57e8d65..e43a4e79bfe8c 100644 --- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr +++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr @@ -46,10 +46,12 @@ LL | pub const fn new(pointer: P) -> Pin

{ | ^^^ error[E0277]: `dyn Future + Send` cannot be unpinned - --> $DIR/expected-boxed-future-isnt-pinned.rs:19:5 + --> $DIR/expected-boxed-future-isnt-pinned.rs:19:14 | LL | Pin::new(x) - | ^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future + Send` + | -------- ^ the trait `Unpin` is not implemented for `dyn Future + Send` + | | + | required by a bound introduced by this call | = note: consider using `Box::pin` note: required by a bound in `Pin::

::new` @@ -59,10 +61,12 @@ LL | impl> Pin

{ | ^^^^^ required by this bound in `Pin::

::new` error[E0277]: `dyn Future + Send` cannot be unpinned - --> $DIR/expected-boxed-future-isnt-pinned.rs:24:5 + --> $DIR/expected-boxed-future-isnt-pinned.rs:24:14 | LL | Pin::new(Box::new(x)) - | ^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future + Send` + | -------- ^^^^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future + Send` + | | + | required by a bound introduced by this call | = note: consider using `Box::pin` note: required by a bound in `Pin::

::new` diff --git a/src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr b/src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr index ba6af8f15fa89..864ab053520db 100644 --- a/src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr +++ b/src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `for<'b> &'b S: Trait` is not satisfied - --> $DIR/imm-ref-trait-object-literal-bound-regions.rs:17:5 + --> $DIR/imm-ref-trait-object-literal-bound-regions.rs:17:14 | LL | foo::(s); - | ^^^^^^^^ the trait `for<'b> Trait` is not implemented for `&'b S` + | -------- ^ the trait `for<'b> Trait` is not implemented for `&'b S` + | | + | required by a bound introduced by this call | = help: the trait `Trait` is implemented for `&'a mut S` = note: `for<'b> Trait` is implemented for `&'b mut S`, but not for `&'b S` diff --git a/src/test/ui/suggestions/imm-ref-trait-object-literal.stderr b/src/test/ui/suggestions/imm-ref-trait-object-literal.stderr index 5f3f62a7b7570..e01102e3864ea 100644 --- a/src/test/ui/suggestions/imm-ref-trait-object-literal.stderr +++ b/src/test/ui/suggestions/imm-ref-trait-object-literal.stderr @@ -21,7 +21,7 @@ error[E0277]: the trait bound `S: Trait` is not satisfied --> $DIR/imm-ref-trait-object-literal.rs:13:7 | LL | foo(s); - | --- ^ expected an implementor of trait `Trait` + | --- ^ the trait `Trait` is not implemented for `S` | | | required by a bound introduced by this call | diff --git a/src/test/ui/suggestions/issue-62843.stderr b/src/test/ui/suggestions/issue-62843.stderr index 607e7992b9f06..62f0943d4c9d9 100644 --- a/src/test/ui/suggestions/issue-62843.stderr +++ b/src/test/ui/suggestions/issue-62843.stderr @@ -2,7 +2,7 @@ error[E0277]: expected a `FnMut<(char,)>` closure, found `String` --> $DIR/issue-62843.rs:4:32 | LL | println!("{:?}", line.find(pattern)); - | ---- ^^^^^^^ expected an implementor of trait `Pattern<'_>` + | ---- ^^^^^^^ the trait `Pattern<'_>` is not implemented for `String` | | | required by a bound introduced by this call | diff --git a/src/test/ui/suggestions/issue-71394-no-from-impl.stderr b/src/test/ui/suggestions/issue-71394-no-from-impl.stderr index a5e6f5b5ffcb0..684db23e1355f 100644 --- a/src/test/ui/suggestions/issue-71394-no-from-impl.stderr +++ b/src/test/ui/suggestions/issue-71394-no-from-impl.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `&[i8]: From<&[u8]>` is not satisfied - --> $DIR/issue-71394-no-from-impl.rs:3:25 + --> $DIR/issue-71394-no-from-impl.rs:3:20 | LL | let _: &[i8] = data.into(); - | ^^^^ the trait `From<&[u8]>` is not implemented for `&[i8]` + | ^^^^ ---- required by a bound introduced by this call + | | + | the trait `From<&[u8]>` is not implemented for `&[i8]` | = help: the following other types implement trait `From`: <[T; LANES] as From>> diff --git a/src/test/ui/suggestions/issue-84973-2.stderr b/src/test/ui/suggestions/issue-84973-2.stderr index 2c54ea6724505..513bf28fb5878 100644 --- a/src/test/ui/suggestions/issue-84973-2.stderr +++ b/src/test/ui/suggestions/issue-84973-2.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `i32: Tr` is not satisfied --> $DIR/issue-84973-2.rs:11:9 | LL | foo(a); - | --- ^ expected an implementor of trait `Tr` + | --- ^ the trait `Tr` is not implemented for `i32` | | | required by a bound introduced by this call | diff --git a/src/test/ui/suggestions/issue-84973-blacklist.stderr b/src/test/ui/suggestions/issue-84973-blacklist.stderr index ae0d3efca4727..c20cc816484b4 100644 --- a/src/test/ui/suggestions/issue-84973-blacklist.stderr +++ b/src/test/ui/suggestions/issue-84973-blacklist.stderr @@ -31,10 +31,12 @@ LL | #[derive(Clone)] | error[E0277]: `[static generator@$DIR/issue-84973-blacklist.rs:17:13: 17:22]` cannot be unpinned - --> $DIR/issue-84973-blacklist.rs:17:5 + --> $DIR/issue-84973-blacklist.rs:17:13 | LL | f_unpin(static || { yield; }); - | ^^^^^^^ the trait `Unpin` is not implemented for `[static generator@$DIR/issue-84973-blacklist.rs:17:13: 17:22]` + | ------- ^^^^^^^^^^^^^^^^^^^^ the trait `Unpin` is not implemented for `[static generator@$DIR/issue-84973-blacklist.rs:17:13: 17:22]` + | | + | required by a bound introduced by this call | = note: consider using `Box::pin` note: required by a bound in `f_unpin` diff --git a/src/test/ui/suggestions/issue-84973-negative.stderr b/src/test/ui/suggestions/issue-84973-negative.stderr index 15559d4ae2c2f..ce838bce09e7b 100644 --- a/src/test/ui/suggestions/issue-84973-negative.stderr +++ b/src/test/ui/suggestions/issue-84973-negative.stderr @@ -17,7 +17,7 @@ error[E0277]: the trait bound `f32: Tr` is not satisfied --> $DIR/issue-84973-negative.rs:11:9 | LL | bar(b); - | --- ^ expected an implementor of trait `Tr` + | --- ^ the trait `Tr` is not implemented for `f32` | | | required by a bound introduced by this call | diff --git a/src/test/ui/suggestions/issue-84973.stderr b/src/test/ui/suggestions/issue-84973.stderr index 24c989ec3e86d..ae2bf5aac40b0 100644 --- a/src/test/ui/suggestions/issue-84973.stderr +++ b/src/test/ui/suggestions/issue-84973.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `Fancy: SomeTrait` is not satisfied --> $DIR/issue-84973.rs:6:24 | LL | let o = Other::new(f); - | ---------- ^ expected an implementor of trait `SomeTrait` + | ---------- ^ the trait `SomeTrait` is not implemented for `Fancy` | | | required by a bound introduced by this call | diff --git a/src/test/ui/suggestions/slice-issue-87994.stderr b/src/test/ui/suggestions/slice-issue-87994.stderr index 44f0da27f1360..84ecd749b0dda 100644 --- a/src/test/ui/suggestions/slice-issue-87994.stderr +++ b/src/test/ui/suggestions/slice-issue-87994.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `[i32]` cannot be known at compilation --> $DIR/slice-issue-87994.rs:3:12 | LL | for _ in v[1..] { - | ^^^^^^ expected an implementor of trait `IntoIterator` + | ^^^^^^ the trait `IntoIterator` is not implemented for `[i32]` | = note: the trait bound `[i32]: IntoIterator` is not satisfied = note: required for `[i32]` to implement `IntoIterator` @@ -17,7 +17,7 @@ error[E0277]: `[i32]` is not an iterator --> $DIR/slice-issue-87994.rs:3:12 | LL | for _ in v[1..] { - | ^^^^^^ expected an implementor of trait `IntoIterator` + | ^^^^^^ the trait `IntoIterator` is not implemented for `[i32]` | = note: the trait bound `[i32]: IntoIterator` is not satisfied = note: required for `[i32]` to implement `IntoIterator` @@ -32,7 +32,7 @@ error[E0277]: the size for values of type `[K]` cannot be known at compilation t --> $DIR/slice-issue-87994.rs:11:13 | LL | for i2 in v2[1..] { - | ^^^^^^^ expected an implementor of trait `IntoIterator` + | ^^^^^^^ the trait `IntoIterator` is not implemented for `[K]` | = note: the trait bound `[K]: IntoIterator` is not satisfied = note: required for `[K]` to implement `IntoIterator` @@ -47,7 +47,7 @@ error[E0277]: `[K]` is not an iterator --> $DIR/slice-issue-87994.rs:11:13 | LL | for i2 in v2[1..] { - | ^^^^^^^ expected an implementor of trait `IntoIterator` + | ^^^^^^^ the trait `IntoIterator` is not implemented for `[K]` | = note: the trait bound `[K]: IntoIterator` is not satisfied = note: required for `[K]` to implement `IntoIterator` diff --git a/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr b/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr index b930d22a3915e..125a8b44f2f0a 100644 --- a/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr +++ b/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `&mut usize: Default` is not satisfied --> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:13:9 | LL | foo(Default::default()); - | ^^^^^^^^^^^^^^^^ expected an implementor of trait `Default` + | ^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&mut usize` | help: consider mutably borrowing here | @@ -13,7 +13,7 @@ error[E0277]: the trait bound `&usize: Default` is not satisfied --> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:14:9 | LL | bar(Default::default()); - | ^^^^^^^^^^^^^^^^ expected an implementor of trait `Default` + | ^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&usize` | help: consider borrowing here | diff --git a/src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr b/src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr index 6b6e406130ec2..6ce9bfd9dcaa2 100644 --- a/src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr +++ b/src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr @@ -2,9 +2,7 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation --> $DIR/suggest-borrow-to-dyn-object.rs:12:11 | LL | check(s); - | ----- ^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^ doesn't have a size known at compile-time | = help: within `OsStr`, the trait `Sized` is not implemented for `[u8]` = note: required because it appears within the type `OsStr` diff --git a/src/test/ui/suggestions/suggest-imm-mut-trait-implementations.stderr b/src/test/ui/suggestions/suggest-imm-mut-trait-implementations.stderr index 6583cabe18489..f2eb651eaa426 100644 --- a/src/test/ui/suggestions/suggest-imm-mut-trait-implementations.stderr +++ b/src/test/ui/suggestions/suggest-imm-mut-trait-implementations.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `A: Trait` is not satisfied --> $DIR/suggest-imm-mut-trait-implementations.rs:20:9 | LL | foo(a); - | --- ^ expected an implementor of trait `Trait` + | --- ^ the trait `Trait` is not implemented for `A` | | | required by a bound introduced by this call | @@ -22,7 +22,7 @@ error[E0277]: the trait bound `B: Trait` is not satisfied --> $DIR/suggest-imm-mut-trait-implementations.rs:21:9 | LL | foo(b); - | --- ^ expected an implementor of trait `Trait` + | --- ^ the trait `Trait` is not implemented for `B` | | | required by a bound introduced by this call | @@ -40,7 +40,7 @@ error[E0277]: the trait bound `C: Trait` is not satisfied --> $DIR/suggest-imm-mut-trait-implementations.rs:22:9 | LL | foo(c); - | --- ^ expected an implementor of trait `Trait` + | --- ^ the trait `Trait` is not implemented for `C` | | | required by a bound introduced by this call | diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.stderr index bfbbe7fd25702..fa7a8a2a09335 100644 --- a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.stderr +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-1.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/check-trait-object-bounds-1.rs:12:5 + --> $DIR/check-trait-object-bounds-1.rs:12:9 | LL | f::>(); - | ^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` + | ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` | = help: the trait `Clone` is implemented for `String` note: required by a bound in `f` diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr index 46e8ce7887493..4084f69a6f04b 100644 --- a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-2.stderr @@ -1,8 +1,8 @@ error[E0277]: expected a `FnOnce<(&i32,)>` closure, found `i32` - --> $DIR/check-trait-object-bounds-2.rs:13:5 + --> $DIR/check-trait-object-bounds-2.rs:13:9 | LL | f:: X<'x, F = i32>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(&i32,)>` closure, found `i32` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(&i32,)>` closure, found `i32` | = help: the trait `for<'r> FnOnce<(&'r i32,)>` is not implemented for `i32` note: required by a bound in `f` diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.stderr index 3ca36d5d2ff19..4891ee9c29f7e 100644 --- a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.stderr +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-4.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `str: Clone` is not satisfied - --> $DIR/check-trait-object-bounds-4.rs:15:5 + --> $DIR/check-trait-object-bounds-4.rs:15:9 | LL | f::>(); - | ^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` + | ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str` | = help: the trait `Clone` is implemented for `String` note: required by a bound in `f` diff --git a/src/test/ui/traits/bad-method-typaram-kind.stderr b/src/test/ui/traits/bad-method-typaram-kind.stderr index 8befa4c5f738b..56acfbe80d03f 100644 --- a/src/test/ui/traits/bad-method-typaram-kind.stderr +++ b/src/test/ui/traits/bad-method-typaram-kind.stderr @@ -1,8 +1,8 @@ error[E0277]: `T` cannot be sent between threads safely - --> $DIR/bad-method-typaram-kind.rs:2:7 + --> $DIR/bad-method-typaram-kind.rs:2:13 | LL | 1.bar::(); - | ^^^ `T` cannot be sent between threads safely + | ^ `T` cannot be sent between threads safely | note: required by a bound in `Bar::bar` --> $DIR/bad-method-typaram-kind.rs:6:14 diff --git a/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs b/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs index 5ba189aa82a41..f9a9347641143 100644 --- a/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs +++ b/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs @@ -2,7 +2,6 @@ fn strip_lf(s: &str) -> &str { s.strip_suffix(b'\n').unwrap_or(s) //~^ ERROR expected a `FnMut<(char,)>` closure, found `u8` //~| NOTE expected an `FnMut<(char,)>` closure, found `u8` - //~| NOTE required by a bound introduced by this call //~| HELP the trait `FnMut<(char,)>` is not implemented for `u8` //~| HELP the following other types implement trait `Pattern<'a>`: //~| NOTE required for `u8` to implement `Pattern<'_>` diff --git a/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr b/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr index 41120c09fb164..ce9ab2d811ae1 100644 --- a/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr +++ b/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr @@ -1,10 +1,8 @@ error[E0277]: expected a `FnMut<(char,)>` closure, found `u8` - --> $DIR/assoc-fn-bound-root-obligation.rs:2:20 + --> $DIR/assoc-fn-bound-root-obligation.rs:2:7 | LL | s.strip_suffix(b'\n').unwrap_or(s) - | ------------ ^^^^^ expected an `FnMut<(char,)>` closure, found `u8` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^ expected an `FnMut<(char,)>` closure, found `u8` | = help: the trait `FnMut<(char,)>` is not implemented for `u8` = help: the following other types implement trait `Pattern<'a>`: diff --git a/src/test/ui/traits/bound/on-structs-and-enums-locals.rs b/src/test/ui/traits/bound/on-structs-and-enums-locals.rs index 21c0ce80f8a8d..60ba343bb0a5c 100644 --- a/src/test/ui/traits/bound/on-structs-and-enums-locals.rs +++ b/src/test/ui/traits/bound/on-structs-and-enums-locals.rs @@ -8,8 +8,8 @@ struct Foo { fn main() { let foo = Foo { - //~^ ERROR E0277 x: 3 + //~^ ERROR E0277 }; let baz: Foo = loop { }; diff --git a/src/test/ui/traits/bound/on-structs-and-enums-locals.stderr b/src/test/ui/traits/bound/on-structs-and-enums-locals.stderr index c9068a270020d..20bbe69c059f8 100644 --- a/src/test/ui/traits/bound/on-structs-and-enums-locals.stderr +++ b/src/test/ui/traits/bound/on-structs-and-enums-locals.stderr @@ -11,10 +11,10 @@ LL | struct Foo { | ^^^^^ required by this bound in `Foo` error[E0277]: the trait bound `{integer}: Trait` is not satisfied - --> $DIR/on-structs-and-enums-locals.rs:10:15 + --> $DIR/on-structs-and-enums-locals.rs:11:12 | -LL | let foo = Foo { - | ^^^ the trait `Trait` is not implemented for `{integer}` +LL | x: 3 + | ^ the trait `Trait` is not implemented for `{integer}` | note: required by a bound in `Foo` --> $DIR/on-structs-and-enums-locals.rs:5:14 diff --git a/src/test/ui/traits/bound/on-structs-and-enums-xc1.rs b/src/test/ui/traits/bound/on-structs-and-enums-xc1.rs index 8156868e048d9..5ef35b513e0fb 100644 --- a/src/test/ui/traits/bound/on-structs-and-enums-xc1.rs +++ b/src/test/ui/traits/bound/on-structs-and-enums-xc1.rs @@ -6,8 +6,8 @@ use on_structs_and_enums_xc::{Bar, Foo, Trait}; fn main() { let foo = Foo { - //~^ ERROR E0277 x: 3 + //~^ ERROR E0277 }; let bar: Bar = return; //~^ ERROR E0277 diff --git a/src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr b/src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr index f4cc64af94f37..3fb5decb723ea 100644 --- a/src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr +++ b/src/test/ui/traits/bound/on-structs-and-enums-xc1.stderr @@ -11,10 +11,10 @@ LL | pub enum Bar { | ^^^^^ required by this bound in `Bar` error[E0277]: the trait bound `{integer}: Trait` is not satisfied - --> $DIR/on-structs-and-enums-xc1.rs:8:15 + --> $DIR/on-structs-and-enums-xc1.rs:9:12 | -LL | let foo = Foo { - | ^^^ the trait `Trait` is not implemented for `{integer}` +LL | x: 3 + | ^ the trait `Trait` is not implemented for `{integer}` | note: required by a bound in `Foo` --> $DIR/auxiliary/on_structs_and_enums_xc.rs:5:18 diff --git a/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr b/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr index cab0ccdf710da..656e0d0bf2662 100644 --- a/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr +++ b/src/test/ui/traits/inheritance/repeated-supertrait-ambig.stderr @@ -1,18 +1,22 @@ error[E0277]: the trait bound `dyn CompareToInts: CompareTo` is not satisfied - --> $DIR/repeated-supertrait-ambig.rs:26:7 + --> $DIR/repeated-supertrait-ambig.rs:26:15 | LL | c.same_as(22) - | ^^^^^^^ the trait `CompareTo` is not implemented for `dyn CompareToInts` + | ------- ^^ the trait `CompareTo` is not implemented for `dyn CompareToInts` + | | + | required by a bound introduced by this call | = help: the following other types implement trait `CompareTo`: > > error[E0277]: the trait bound `C: CompareTo` is not satisfied - --> $DIR/repeated-supertrait-ambig.rs:30:7 + --> $DIR/repeated-supertrait-ambig.rs:30:15 | LL | c.same_as(22) - | ^^^^^^^ the trait `CompareTo` is not implemented for `C` + | ------- ^^ the trait `CompareTo` is not implemented for `C` + | | + | required by a bound introduced by this call | help: consider further restricting this bound | @@ -20,20 +24,24 @@ LL | fn with_trait>(c: &C) -> bool { | ++++++++++++++++ error[E0277]: the trait bound `dyn CompareToInts: CompareTo` is not satisfied - --> $DIR/repeated-supertrait-ambig.rs:34:5 + --> $DIR/repeated-supertrait-ambig.rs:34:37 | LL | ::same_as(c, 22) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `CompareTo` is not implemented for `dyn CompareToInts` + | ---------------------------- ^^ the trait `CompareTo` is not implemented for `dyn CompareToInts` + | | + | required by a bound introduced by this call | = help: the following other types implement trait `CompareTo`: > > error[E0277]: the trait bound `C: CompareTo` is not satisfied - --> $DIR/repeated-supertrait-ambig.rs:38:5 + --> $DIR/repeated-supertrait-ambig.rs:38:27 | LL | CompareTo::same_as(c, 22) - | ^^^^^^^^^^^^^^^^^^ the trait `CompareTo` is not implemented for `C` + | ------------------ ^^ the trait `CompareTo` is not implemented for `C` + | | + | required by a bound introduced by this call | help: consider further restricting this bound | @@ -41,10 +49,12 @@ LL | fn with_ufcs2>(c: &C) -> bool { | ++++++++++++++++ error[E0277]: the trait bound `i64: CompareTo` is not satisfied - --> $DIR/repeated-supertrait-ambig.rs:42:23 + --> $DIR/repeated-supertrait-ambig.rs:42:31 | LL | assert_eq!(22_i64.same_as(22), true); - | ^^^^^^^ the trait `CompareTo` is not implemented for `i64` + | ------- ^^ the trait `CompareTo` is not implemented for `i64` + | | + | required by a bound introduced by this call | = help: the following other types implement trait `CompareTo`: > diff --git a/src/test/ui/traits/issue-77982.stderr b/src/test/ui/traits/issue-77982.stderr index 2b832e27c5224..e210f11b3e0c1 100644 --- a/src/test/ui/traits/issue-77982.stderr +++ b/src/test/ui/traits/issue-77982.stderr @@ -2,7 +2,9 @@ error[E0283]: type annotations needed --> $DIR/issue-77982.rs:8:10 | LL | opts.get(opt.as_ref()); - | ^^^ cannot infer type of the type parameter `Q` declared on the associated function `get` + | ^^^ ------------ type must be known at this point + | | + | cannot infer type of the type parameter `Q` declared on the associated function `get` | = note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`: - impl Borrow for String; @@ -13,7 +15,7 @@ note: required by a bound in `HashMap::::get` | LL | K: Borrow, | ^^^^^^^^^ required by this bound in `HashMap::::get` -help: consider specifying the type argument in the function call +help: consider specifying the generic argument | LL | opts.get::(opt.as_ref()); | +++++ @@ -42,7 +44,7 @@ error[E0283]: type annotations needed LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(); | --------- ^^^^ | | - | type must be known at this point + | required by a bound introduced by this call | = note: multiple `impl`s satisfying `u32: From<_>` found in the following crates: `core`, `std`: - impl From for u32; diff --git a/src/test/ui/traits/issue-97576.stderr b/src/test/ui/traits/issue-97576.stderr index 9062a0fab630a..146d38d076a3c 100644 --- a/src/test/ui/traits/issue-97576.stderr +++ b/src/test/ui/traits/issue-97576.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `String: From` is not satisfied - --> $DIR/issue-97576.rs:8:22 + --> $DIR/issue-97576.rs:8:18 | LL | bar: bar.into(), - | ^^^^ the trait `From` is not implemented for `String` + | ^^^ ---- required by a bound introduced by this call + | | + | the trait `From` is not implemented for `String` | = note: required for `impl ToString` to implement `Into` diff --git a/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr b/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr index cbec359342148..6e6172eea4746 100644 --- a/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr +++ b/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr @@ -13,7 +13,9 @@ error[E0283]: type annotations needed --> $DIR/multidispatch-convert-ambig-dest.rs:26:5 | LL | test(22, std::default::Default::default()); - | ^^^^ cannot infer type of the type parameter `U` declared on the function `test` + | ^^^^ -------------------------------- type must be known at this point + | | + | cannot infer type of the type parameter `U` declared on the function `test` | note: multiple `impl`s satisfying `i32: Convert<_>` found --> $DIR/multidispatch-convert-ambig-dest.rs:8:1 @@ -30,10 +32,10 @@ LL | fn test(_: T, _: U) | ---- required by a bound in this LL | where T : Convert | ^^^^^^^^^^ required by this bound in `test` -help: consider specifying the type arguments in the function call +help: consider specifying the generic arguments | -LL | test::(22, std::default::Default::default()); - | ++++++++ +LL | test::(22, std::default::Default::default()); + | ++++++++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr b/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr index bf7c3bcc6aa9b..41fc3600fcd54 100644 --- a/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr +++ b/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr @@ -61,7 +61,7 @@ error[E0277]: `dummy2::TestType` cannot be sent between threads safely --> $DIR/negated-auto-traits-error.rs:48:13 | LL | is_send(Box::new(TestType)); - | ------- ^^^^^^^^^^^^^^^^^^ expected an implementor of trait `Send` + | ------- ^^^^^^^^^^^^^^^^^^ the trait `Send` is not implemented for `Unique` | | | required by a bound introduced by this call | diff --git a/src/test/ui/traits/suggest-where-clause.stderr b/src/test/ui/traits/suggest-where-clause.stderr index d4d9b4967478a..747e2477b9cf1 100644 --- a/src/test/ui/traits/suggest-where-clause.stderr +++ b/src/test/ui/traits/suggest-where-clause.stderr @@ -19,13 +19,13 @@ LL + fn check() { | error[E0277]: the size for values of type `U` cannot be known at compilation time - --> $DIR/suggest-where-clause.rs:10:5 + --> $DIR/suggest-where-clause.rs:10:20 | LL | fn check() { | - this type parameter needs to be `std::marker::Sized` ... LL | mem::size_of::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^ doesn't have a size known at compile-time | note: required because it appears within the type `Misc` --> $DIR/suggest-where-clause.rs:3:8 diff --git a/src/test/ui/transmutability/references.stderr b/src/test/ui/transmutability/references.stderr index b1359ea586583..17ffcf64177e3 100644 --- a/src/test/ui/transmutability/references.stderr +++ b/src/test/ui/transmutability/references.stderr @@ -1,8 +1,8 @@ error[E0277]: `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context`. - --> $DIR/references.rs:19:37 + --> $DIR/references.rs:19:52 | LL | assert::is_maybe_transmutable::<&'static Unit, &'static Unit>(); - | ^^^^^^^^^^^^^ `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context`. + | ^^^^^^^^^^^^^ `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context`. | = help: the trait `BikeshedIntrinsicFrom<&'static Unit, assert::Context, true, true, true, true>` is not implemented for `&'static Unit` note: required by a bound in `is_maybe_transmutable` diff --git a/src/test/ui/type/type-params-in-different-spaces-2.stderr b/src/test/ui/type/type-params-in-different-spaces-2.stderr index 53610985f31da..220b3929c8857 100644 --- a/src/test/ui/type/type-params-in-different-spaces-2.stderr +++ b/src/test/ui/type/type-params-in-different-spaces-2.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `Self: Tr` is not satisfied - --> $DIR/type-params-in-different-spaces-2.rs:10:9 + --> $DIR/type-params-in-different-spaces-2.rs:10:16 | LL | Tr::op(u) - | ^^^^^^ the trait `Tr` is not implemented for `Self` + | ------ ^ the trait `Tr` is not implemented for `Self` + | | + | required by a bound introduced by this call | help: consider further restricting `Self` | @@ -10,10 +12,12 @@ LL | fn test(u: U) -> Self where Self: Tr { | +++++++++++++++++ error[E0277]: the trait bound `Self: Tr` is not satisfied - --> $DIR/type-params-in-different-spaces-2.rs:16:9 + --> $DIR/type-params-in-different-spaces-2.rs:16:16 | LL | Tr::op(u) - | ^^^^^^ the trait `Tr` is not implemented for `Self` + | ------ ^ the trait `Tr` is not implemented for `Self` + | | + | required by a bound introduced by this call | help: consider further restricting `Self` | diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr index 6bb5e1f54272b..b9fca1a1b54b8 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr +++ b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr @@ -12,10 +12,10 @@ LL | fn is_sync() {} | ^^^^ required by this bound in `is_sync` error[E0277]: `UnsafeCell` cannot be shared between threads safely - --> $DIR/typeck-default-trait-impl-negation-sync.rs:36:5 + --> $DIR/typeck-default-trait-impl-negation-sync.rs:36:15 | LL | is_sync::(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` cannot be shared between threads safely + | ^^^^^^^^^^^^^ `UnsafeCell` cannot be shared between threads safely | = help: within `MyTypeWUnsafe`, the trait `Sync` is not implemented for `UnsafeCell` note: required because it appears within the type `MyTypeWUnsafe` @@ -30,10 +30,10 @@ LL | fn is_sync() {} | ^^^^ required by this bound in `is_sync` error[E0277]: `Managed` cannot be shared between threads safely - --> $DIR/typeck-default-trait-impl-negation-sync.rs:39:5 + --> $DIR/typeck-default-trait-impl-negation-sync.rs:39:15 | LL | is_sync::(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ `Managed` cannot be shared between threads safely + | ^^^^^^^^^^^^^ `Managed` cannot be shared between threads safely | = help: within `MyTypeManaged`, the trait `Sync` is not implemented for `Managed` note: required because it appears within the type `MyTypeManaged` diff --git a/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr index c6f9b3661a232..f08c81bc1e937 100644 --- a/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr +++ b/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr @@ -1,8 +1,10 @@ error[E0277]: cannot add `u32` to `i32` - --> $DIR/ufcs-qpath-self-mismatch.rs:4:5 + --> $DIR/ufcs-qpath-self-mismatch.rs:4:31 | LL | >::add(1, 2); - | ^^^^^^^^^^^^^^^^^^^^^^ no implementation for `i32 + u32` + | ---------------------- ^ no implementation for `i32 + u32` + | | + | required by a bound introduced by this call | = help: the trait `Add` is not implemented for `i32` = help: the following other types implement trait `Add`: diff --git a/src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr b/src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr index 85ff49d61a3ff..635ebbb71d070 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr @@ -6,7 +6,17 @@ LL | let c = || drop(y.0); | | | this closure implements `FnOnce`, not `Fn` LL | foo(c); - | --- the requirement to implement `Fn` derives from here + | --- - the requirement to implement `Fn` derives from here + | | + | required by a bound introduced by this call + | +note: required by a bound in `foo` + --> $DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:4:14 + | +LL | fn foo(f: F) + | --- required by a bound in this +LL | where F: Fn() + | ^^^^ required by this bound in `foo` error: aborting due to previous error diff --git a/src/test/ui/union/union-generic.mirunsafeck.stderr b/src/test/ui/union/union-generic.mirunsafeck.stderr index a4f0c400d7310..037022a91fcd0 100644 --- a/src/test/ui/union/union-generic.mirunsafeck.stderr +++ b/src/test/ui/union/union-generic.mirunsafeck.stderr @@ -11,10 +11,10 @@ LL | union U { | ^^^^ required by this bound in `U` error[E0277]: the trait bound `Rc: Copy` is not satisfied - --> $DIR/union-generic.rs:13:13 + --> $DIR/union-generic.rs:13:17 | LL | let u = U::> { a: Default::default() }; - | ^^^^^^^^^^^^ the trait `Copy` is not implemented for `Rc` + | ^^^^^^^ the trait `Copy` is not implemented for `Rc` | note: required by a bound in `U` --> $DIR/union-generic.rs:6:12 diff --git a/src/test/ui/union/union-generic.thirunsafeck.stderr b/src/test/ui/union/union-generic.thirunsafeck.stderr index a4f0c400d7310..037022a91fcd0 100644 --- a/src/test/ui/union/union-generic.thirunsafeck.stderr +++ b/src/test/ui/union/union-generic.thirunsafeck.stderr @@ -11,10 +11,10 @@ LL | union U { | ^^^^ required by this bound in `U` error[E0277]: the trait bound `Rc: Copy` is not satisfied - --> $DIR/union-generic.rs:13:13 + --> $DIR/union-generic.rs:13:17 | LL | let u = U::> { a: Default::default() }; - | ^^^^^^^^^^^^ the trait `Copy` is not implemented for `Rc` + | ^^^^^^^ the trait `Copy` is not implemented for `Rc` | note: required by a bound in `U` --> $DIR/union-generic.rs:6:12 diff --git a/src/test/ui/unsized-locals/unsized-exprs.stderr b/src/test/ui/unsized-locals/unsized-exprs.stderr index 6960255d98797..a7f57e3fd1566 100644 --- a/src/test/ui/unsized-locals/unsized-exprs.stderr +++ b/src/test/ui/unsized-locals/unsized-exprs.stderr @@ -12,9 +12,7 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation --> $DIR/unsized-exprs.rs:24:22 | LL | udrop::>(A { 0: *foo() }); - | ---------------- ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: within `A<[u8]>`, the trait `Sized` is not implemented for `[u8]` note: required because it appears within the type `A<[u8]>` diff --git a/src/test/ui/unsized/issue-30355.stderr b/src/test/ui/unsized/issue-30355.stderr index d7af558eef42a..f5491552a45d2 100644 --- a/src/test/ui/unsized/issue-30355.stderr +++ b/src/test/ui/unsized/issue-30355.stderr @@ -2,9 +2,7 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation --> $DIR/issue-30355.rs:5:8 | LL | &X(*Y) - | - ^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` = help: unsized fn params are gated as an unstable feature diff --git a/src/test/ui/unsized/issue-71659.stderr b/src/test/ui/unsized/issue-71659.stderr index d7b95f55769fd..50060e53a49d6 100644 --- a/src/test/ui/unsized/issue-71659.stderr +++ b/src/test/ui/unsized/issue-71659.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied - --> $DIR/issue-71659.rs:30:15 + --> $DIR/issue-71659.rs:30:13 | LL | let x = x.cast::<[i32]>(); - | ^^^^ the trait `CastTo<[i32]>` is not implemented for `dyn Foo` + | ^ ---- required by a bound introduced by this call + | | + | the trait `CastTo<[i32]>` is not implemented for `dyn Foo` | note: required by a bound in `Cast::cast` --> $DIR/issue-71659.rs:19:15 diff --git a/src/test/ui/unsized/issue-75707.stderr b/src/test/ui/unsized/issue-75707.stderr index 7d0a2cb85b612..97618ed05ed38 100644 --- a/src/test/ui/unsized/issue-75707.stderr +++ b/src/test/ui/unsized/issue-75707.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `MyCall: Callback` is not satisfied - --> $DIR/issue-75707.rs:15:5 + --> $DIR/issue-75707.rs:15:9 | LL | f::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Callback` is not implemented for `MyCall` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Callback` is not implemented for `MyCall` | note: required by a bound in `f` --> $DIR/issue-75707.rs:9:9 diff --git a/src/test/ui/unsized/unsized-fn-param.stderr b/src/test/ui/unsized/unsized-fn-param.stderr index 0221ef16b4965..b477260543258 100644 --- a/src/test/ui/unsized/unsized-fn-param.stderr +++ b/src/test/ui/unsized/unsized-fn-param.stderr @@ -2,9 +2,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t --> $DIR/unsized-fn-param.rs:11:11 | LL | foo11("bar", &"baz"); - | ----- ^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` = note: required for the cast from `str` to the object type `dyn AsRef` @@ -17,9 +15,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t --> $DIR/unsized-fn-param.rs:13:19 | LL | foo12(&"bar", "baz"); - | ----- ^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` = note: required for the cast from `str` to the object type `dyn AsRef` @@ -32,9 +28,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t --> $DIR/unsized-fn-param.rs:16:11 | LL | foo21("bar", &"baz"); - | ----- ^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` = note: required for the cast from `str` to the object type `dyn AsRef` @@ -47,9 +41,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t --> $DIR/unsized-fn-param.rs:18:19 | LL | foo22(&"bar", "baz"); - | ----- ^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` = note: required for the cast from `str` to the object type `dyn AsRef` diff --git a/src/test/ui/unsized/unsized-struct.stderr b/src/test/ui/unsized/unsized-struct.stderr index c9510e92fecb4..dff1b0a5112a4 100644 --- a/src/test/ui/unsized/unsized-struct.stderr +++ b/src/test/ui/unsized/unsized-struct.stderr @@ -25,10 +25,10 @@ LL + fn foo2() { not_sized::>() } | error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/unsized-struct.rs:13:24 + --> $DIR/unsized-struct.rs:13:35 | LL | fn bar2() { is_sized::>() } - | - ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | - ^^^^^^ doesn't have a size known at compile-time | | | this type parameter needs to be `std::marker::Sized` | diff --git a/src/test/ui/unsized/unsized3.stderr b/src/test/ui/unsized/unsized3.stderr index d64091b15eb1f..9ad1ac6b4df61 100644 --- a/src/test/ui/unsized/unsized3.stderr +++ b/src/test/ui/unsized/unsized3.stderr @@ -79,14 +79,12 @@ LL | fn f5(x: &Y) {} | ++++++++ error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized3.rs:40:8 + --> $DIR/unsized3.rs:40:5 | LL | fn f9(x1: Box>) { | - this type parameter needs to be `std::marker::Sized` LL | f5(&(*x1, 34)); - | -- ^^^^^^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^ doesn't have a size known at compile-time | note: required because it appears within the type `S` --> $DIR/unsized3.rs:28:8 @@ -106,9 +104,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim LL | fn f10(x1: Box>) { | - this type parameter needs to be `std::marker::Sized` LL | f5(&(32, *x1)); - | -- ^^^^^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call + | ^^^^^^^^^ doesn't have a size known at compile-time | note: required because it appears within the type `S` --> $DIR/unsized3.rs:28:8 diff --git a/src/test/ui/where-clauses/where-clause-method-substituion.stderr b/src/test/ui/where-clauses/where-clause-method-substituion.stderr index f431deee73f9a..8c47ed6d4317a 100644 --- a/src/test/ui/where-clauses/where-clause-method-substituion.stderr +++ b/src/test/ui/where-clauses/where-clause-method-substituion.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `X: Foo` is not satisfied - --> $DIR/where-clause-method-substituion.rs:20:7 + --> $DIR/where-clause-method-substituion.rs:20:16 | LL | 1.method::(); - | ^^^^^^ the trait `Foo` is not implemented for `X` + | ^ the trait `Foo` is not implemented for `X` | note: required by a bound in `Bar::method` --> $DIR/where-clause-method-substituion.rs:6:34 diff --git a/src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr b/src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr index c13552bc26eee..e90502977ff6a 100644 --- a/src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr +++ b/src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr @@ -1,10 +1,8 @@ error[E0277]: the trait bound `Bar: Eq` is not satisfied - --> $DIR/where-clauses-method-unsatisfied.rs:18:14 + --> $DIR/where-clauses-method-unsatisfied.rs:18:7 | LL | x.equals(&x); - | ------ ^^ the trait `Eq` is not implemented for `Bar` - | | - | required by a bound introduced by this call + | ^^^^^^ the trait `Eq` is not implemented for `Bar` | note: required by a bound in `Foo::::equals` --> $DIR/where-clauses-method-unsatisfied.rs:11:52 diff --git a/src/tools/rustfmt/src/attr.rs b/src/tools/rustfmt/src/attr.rs index 41ba9a847e67a..f5c1ee5fdd121 100644 --- a/src/tools/rustfmt/src/attr.rs +++ b/src/tools/rustfmt/src/attr.rs @@ -49,10 +49,7 @@ pub(crate) fn get_span_without_attrs(stmt: &ast::Stmt) -> Span { } /// Returns attributes that are within `outer_span`. -pub(crate) fn filter_inline_attrs( - attrs: &[ast::Attribute], - outer_span: Span, -) -> Vec { +pub(crate) fn filter_inline_attrs(attrs: &[ast::Attribute], outer_span: Span) -> ast::AttrVec { attrs .iter() .filter(|a| outer_span.lo() <= a.span.lo() && a.span.hi() <= outer_span.hi()) diff --git a/src/tools/rustfmt/src/imports.rs b/src/tools/rustfmt/src/imports.rs index 8d41c881589e5..b6530c69243ed 100644 --- a/src/tools/rustfmt/src/imports.rs +++ b/src/tools/rustfmt/src/imports.rs @@ -116,7 +116,7 @@ pub(crate) struct UseTree { // Additional fields for top level use items. // Should we have another struct for top-level use items rather than reusing this? visibility: Option, - attrs: Option>, + attrs: Option, } impl PartialEq for UseTree { @@ -417,7 +417,7 @@ impl UseTree { list_item: Option, visibility: Option, opt_lo: Option, - attrs: Option>, + attrs: Option, ) -> UseTree { let span = if let Some(lo) = opt_lo { mk_sp(lo, a.span.hi()) diff --git a/src/tools/rustfmt/src/modules.rs b/src/tools/rustfmt/src/modules.rs index 81da724329f02..7a0d1736c59a6 100644 --- a/src/tools/rustfmt/src/modules.rs +++ b/src/tools/rustfmt/src/modules.rs @@ -26,7 +26,7 @@ type FileModMap<'ast> = BTreeMap>; pub(crate) struct Module<'a> { ast_mod_kind: Option>, pub(crate) items: Cow<'a, Vec>>, - inner_attr: Vec, + inner_attr: ast::AttrVec, pub(crate) span: Span, } @@ -35,7 +35,7 @@ impl<'a> Module<'a> { mod_span: Span, ast_mod_kind: Option>, mod_items: Cow<'a, Vec>>, - mod_attrs: Cow<'a, Vec>, + mod_attrs: Cow<'a, ast::AttrVec>, ) -> Self { let inner_attr = mod_attrs .iter() @@ -158,7 +158,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { module_item.item.span, Some(Cow::Owned(sub_mod_kind.clone())), Cow::Owned(vec![]), - Cow::Owned(vec![]), + Cow::Owned(ast::AttrVec::new()), ), )?; } @@ -185,7 +185,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { span, Some(Cow::Owned(sub_mod_kind.clone())), Cow::Owned(vec![]), - Cow::Owned(vec![]), + Cow::Owned(ast::AttrVec::new()), ), )?; } diff --git a/src/tools/rustfmt/src/parse/parser.rs b/src/tools/rustfmt/src/parse/parser.rs index 268c72649a65a..e0bd065518b3d 100644 --- a/src/tools/rustfmt/src/parse/parser.rs +++ b/src/tools/rustfmt/src/parse/parser.rs @@ -109,7 +109,7 @@ impl<'a> Parser<'a> { sess: &'a ParseSess, path: &Path, span: Span, - ) -> Result<(Vec, Vec>, Span), ParserError> { + ) -> Result<(ast::AttrVec, Vec>, Span), ParserError> { let result = catch_unwind(AssertUnwindSafe(|| { let mut parser = new_parser_from_file(sess.inner(), path, Some(span)); match parser.parse_mod(&TokenKind::Eof) { diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 3cf44a2d7d1ef..dee58ff2fb510 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -125,16 +125,13 @@ fn should_ignore(line: &str) -> bool { /// Returns `true` if `line` is allowed to be longer than the normal limit. fn long_line_is_ok(extension: &str, is_error_code: bool, max_columns: usize, line: &str) -> bool { - if extension != "md" || is_error_code { - if line_is_url(is_error_code, max_columns, line) || should_ignore(line) { - return true; - } - } else if extension == "md" { + match extension { + // fluent files are allowed to be any length + "ftl" => true, // non-error code markdown is allowed to be any length - return true; + "md" if !is_error_code => true, + _ => line_is_url(is_error_code, max_columns, line) || should_ignore(line), } - - false } enum Directive { @@ -230,7 +227,7 @@ pub fn check(path: &Path, bad: &mut bool) { super::walk(path, &mut skip, &mut |entry, contents| { let file = entry.path(); let filename = file.file_name().unwrap().to_string_lossy(); - let extensions = [".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h", ".md", ".css"]; + let extensions = [".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h", ".md", ".css", ".ftl"]; if extensions.iter().all(|e| !filename.ends_with(e)) || filename.starts_with(".#") { return; } From ac4ccebb24995bf73a8c5ebeb7eec05d460f4908 Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Mon, 22 Aug 2022 16:01:53 +0800 Subject: [PATCH 05/10] tidy up spaces in .ftl --- compiler/rustc_error_messages/locales/en-US/borrowck.ftl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index d89053a99d277..6032e65a57d27 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -51,5 +51,4 @@ borrowck_returned_lifetime_wrong = {$mir_def_name} was supposed to return data with lifetime `{$outlived_fr_name}` but it is returning data with lifetime `{$fr_name}` borrowck_returned_lifetime_short = - {$category_desc}requires that `{$free_region_name}` must outlive `{$outlived_fr_name}`" - + {$category_desc}requires that `{$free_region_name}` must outlive `{$outlived_fr_name}` From 8edf4599335b1fdfb6b4c616c91ca55792ef33ea Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Mon, 22 Aug 2022 18:10:28 +0800 Subject: [PATCH 06/10] `err.subdiag` on `MultiSpan` --- .../rustc_borrowck/src/diagnostics/region_errors.rs | 4 ++-- compiler/rustc_borrowck/src/session_diagnostics.rs | 10 ++++++++++ .../rustc_error_messages/locales/en-US/borrowck.ftl | 3 +++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 6894ec7956cfe..4f730262e0eb9 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -27,7 +27,7 @@ use rustc_span::Span; use crate::borrowck_errors; use crate::session_diagnostics::{ FnMutError, FnMutReturnTypeErr, GenericDoesNotLiveLongEnough, LifeTimeOutLiveErr, - LifeTimeReturnCategoryErr, + LifeTimeReturnCategoryErr, RequireStaticErr, }; use super::{OutlivesSuggestionBuilder, RegionName}; @@ -854,7 +854,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ident.span, "calling this method introduces the `impl`'s 'static` requirement", ); - err.span_note(multi_span, "the used `impl` has a `'static` requirement"); + err.subdiagnostic(RequireStaticErr::UsedImpl { multi_span }); err.span_suggestion_verbose( span.shrink_to_hi(), "consider relaxing the implicit `'static` requirement", diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index ff2196760039c..8c78c8589b8aa 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -1,3 +1,4 @@ +use rustc_errors::MultiSpan; use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_middle::ty::Ty; use rustc_span::Span; @@ -122,3 +123,12 @@ pub(crate) enum LifeTimeReturnCategoryErr { outlived_fr_name: String, }, } + +#[derive(SessionSubdiagnostic)] +pub(crate) enum RequireStaticErr { + #[note(borrowck::used_impl_require_static)] + UsedImpl { + #[primary_span] + multi_span: MultiSpan, + }, +} diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index 6032e65a57d27..94fd9b89d3544 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -52,3 +52,6 @@ borrowck_returned_lifetime_wrong = borrowck_returned_lifetime_short = {$category_desc}requires that `{$free_region_name}` must outlive `{$outlived_fr_name}` + +borrowck_used_impl_require_static = + the used `impl` has a `'static` requirement From c5d4efd2948ea67705e90dfb609a31563dd680de Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Mon, 22 Aug 2022 18:39:01 +0800 Subject: [PATCH 07/10] fix typo : "" --- compiler/rustc_error_messages/locales/en-US/borrowck.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index 94fd9b89d3544..5da1f59168a6d 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -31,7 +31,7 @@ borrowck_var_cannot_escape_closure = captured variable cannot escape `FnMut` closure body .upvar_def = variable defined here .upvar = variable captured here - .fr = "inferred to be a `FnMut` closure" + .fr = inferred to be a `FnMut` closure .note = `FnMut` closures only have access to their captured variables while they are executing... .cannot_escape = ...therefore, they cannot allow references to captured variables to escape From 408689db7c73cbd39c57595572c52ca96ad8f542 Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Mon, 22 Aug 2022 20:21:15 +0800 Subject: [PATCH 08/10] fix ui --- .../src/diagnostics/region_errors.rs | 26 ++++++++++--------- compiler/rustc_borrowck/src/lib.rs | 3 ++- .../rustc_borrowck/src/session_diagnostics.rs | 12 ++++++++- .../locales/en-US/borrowck.ftl | 20 +++++++++----- 4 files changed, 41 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 6894ec7956cfe..66b036d194af9 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -27,7 +27,7 @@ use rustc_span::Span; use crate::borrowck_errors; use crate::session_diagnostics::{ FnMutError, FnMutReturnTypeErr, GenericDoesNotLiveLongEnough, LifeTimeOutLiveErr, - LifeTimeReturnCategoryErr, + LifeTimeReturnCategoryErr, RequireStaticErr, }; use super::{OutlivesSuggestionBuilder, RegionName}; @@ -500,17 +500,17 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { debug!("report_fnmut_error: output_ty={:?}", output_ty); - let ty_err = match output_ty.kind() { - ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span }, - ty::Adt(def, _) if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) => { - FnMutReturnTypeErr::ReturnAsyncBlock { span: *span } - } - _ => FnMutReturnTypeErr::ReturnRef { span: *span }, - }; - let mut err = FnMutError { span: *span, - ty_err, + ty_err: match output_ty.kind() { + ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span }, + ty::Adt(def, _) + if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) => + { + FnMutReturnTypeErr::ReturnAsyncBlock { span: *span } + } + _ => FnMutReturnTypeErr::ReturnRef { span: *span }, + }, upvar_def_span: None, upvar_span: None, fr_span: None, @@ -682,6 +682,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let (_, mir_def_name) = self.infcx.tcx.article_and_description(self.mir_def_id().to_def_id()); + let mut err = LifeTimeOutLiveErr { span: *span, category: None }; + let fr_name = self.give_region_a_name(*fr).unwrap(); let outlived_fr_name = self.give_region_a_name(*outlived_fr).unwrap(); @@ -700,7 +702,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }, }; - let err = LifeTimeOutLiveErr { span: *span, category: err_category }; + err.category = Some(err_category); let mut diag = self.infcx.tcx.sess.create_err(err); @@ -854,7 +856,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ident.span, "calling this method introduces the `impl`'s 'static` requirement", ); - err.span_note(multi_span, "the used `impl` has a `'static` requirement"); + err.subdiagnostic(RequireStaticErr::UsedImpl { multi_span }); err.span_suggestion_verbose( span.shrink_to_hi(), "consider relaxing the implicit `'static` requirement", diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 78c817150a65a..6333b771cece3 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -426,7 +426,8 @@ fn do_mir_borrowck<'a, 'tcx>( continue; } - tcx.emit_spanned_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span }) + let mut_span = tcx.sess.source_map().span_until_non_whitespace(span); + tcx.emit_spanned_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span }) } let tainted_by_errors = mbcx.emit_errors(); diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index ff2196760039c..3490c2dae5729 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -1,3 +1,4 @@ +use rustc_errors::MultiSpan; use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_middle::ty::Ty; use rustc_span::Span; @@ -100,7 +101,7 @@ pub(crate) struct LifeTimeOutLiveErr { #[primary_span] pub span: Span, #[subdiagnostic] - pub category: LifeTimeReturnCategoryErr, + pub category: Option, } #[derive(SessionSubdiagnostic)] @@ -122,3 +123,12 @@ pub(crate) enum LifeTimeReturnCategoryErr { outlived_fr_name: String, }, } + +#[derive(SessionSubdiagnostic)] +pub(crate) enum RequireStaticErr { + #[note(borrowck::used_impl_require_static)] + UsedImpl { + #[primary_span] + multi_span: MultiSpan, + }, +} diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index 6032e65a57d27..dbeaa564094f7 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -25,21 +25,25 @@ borrowck_var_does_not_need_mut = .suggestion = remove this `mut` borrowck_const_not_used_in_type_alias = - const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias + const parameter `{$ct}` is part of concrete type but not + used in parameter list for the `impl Trait` type alias borrowck_var_cannot_escape_closure = captured variable cannot escape `FnMut` closure body .upvar_def = variable defined here .upvar = variable captured here - .fr = "inferred to be a `FnMut` closure" - .note = `FnMut` closures only have access to their captured variables while they are executing... + .fr = inferred to be a `FnMut` closure + .note = `FnMut` closures only have access to their captured variables while they are + executing... .cannot_escape = ...therefore, they cannot allow references to captured variables to escape borrowck_returned_closure_escaped = - returns a closure that contains a reference to a captured variable, which then escapes the closure body + returns a closure that contains a reference to a captured variable, which then + escapes the closure body borrowck_returned_async_block_escaped = - returns an `async` block that contains a reference to a captured variable, which then escapes the closure body + returns an `async` block that contains a reference to a captured variable, which then + escapes the closure body borrowck_returned_ref_escaped = returns a reference to a captured variable which escapes the closure body @@ -48,7 +52,11 @@ borrowck_lifetime_constraints_error = lifetime may not live long enough borrowck_returned_lifetime_wrong = - {$mir_def_name} was supposed to return data with lifetime `{$outlived_fr_name}` but it is returning data with lifetime `{$fr_name}` + {$mir_def_name} was supposed to return data with lifetime `{$outlived_fr_name}` but it is returning + data with lifetime `{$fr_name}` borrowck_returned_lifetime_short = {$category_desc}requires that `{$free_region_name}` must outlive `{$outlived_fr_name}` + +borrowck_used_impl_require_static = + the used `impl` has a `'static` requirement From b7aa1cc2f00bf0fe1d16e42aebd131528a518aba Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Mon, 22 Aug 2022 20:28:31 +0800 Subject: [PATCH 09/10] ui fix --- .../src/diagnostics/region_errors.rs | 26 +++++++++---------- compiler/rustc_borrowck/src/lib.rs | 3 +-- .../rustc_borrowck/src/session_diagnostics.rs | 12 +-------- .../locales/en-US/borrowck.ftl | 1 - 4 files changed, 14 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 66b036d194af9..6894ec7956cfe 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -27,7 +27,7 @@ use rustc_span::Span; use crate::borrowck_errors; use crate::session_diagnostics::{ FnMutError, FnMutReturnTypeErr, GenericDoesNotLiveLongEnough, LifeTimeOutLiveErr, - LifeTimeReturnCategoryErr, RequireStaticErr, + LifeTimeReturnCategoryErr, }; use super::{OutlivesSuggestionBuilder, RegionName}; @@ -500,17 +500,17 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { debug!("report_fnmut_error: output_ty={:?}", output_ty); + let ty_err = match output_ty.kind() { + ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span }, + ty::Adt(def, _) if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) => { + FnMutReturnTypeErr::ReturnAsyncBlock { span: *span } + } + _ => FnMutReturnTypeErr::ReturnRef { span: *span }, + }; + let mut err = FnMutError { span: *span, - ty_err: match output_ty.kind() { - ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span }, - ty::Adt(def, _) - if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) => - { - FnMutReturnTypeErr::ReturnAsyncBlock { span: *span } - } - _ => FnMutReturnTypeErr::ReturnRef { span: *span }, - }, + ty_err, upvar_def_span: None, upvar_span: None, fr_span: None, @@ -682,8 +682,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let (_, mir_def_name) = self.infcx.tcx.article_and_description(self.mir_def_id().to_def_id()); - let mut err = LifeTimeOutLiveErr { span: *span, category: None }; - let fr_name = self.give_region_a_name(*fr).unwrap(); let outlived_fr_name = self.give_region_a_name(*outlived_fr).unwrap(); @@ -702,7 +700,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }, }; - err.category = Some(err_category); + let err = LifeTimeOutLiveErr { span: *span, category: err_category }; let mut diag = self.infcx.tcx.sess.create_err(err); @@ -856,7 +854,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ident.span, "calling this method introduces the `impl`'s 'static` requirement", ); - err.subdiagnostic(RequireStaticErr::UsedImpl { multi_span }); + err.span_note(multi_span, "the used `impl` has a `'static` requirement"); err.span_suggestion_verbose( span.shrink_to_hi(), "consider relaxing the implicit `'static` requirement", diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 6333b771cece3..78c817150a65a 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -426,8 +426,7 @@ fn do_mir_borrowck<'a, 'tcx>( continue; } - let mut_span = tcx.sess.source_map().span_until_non_whitespace(span); - tcx.emit_spanned_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span }) + tcx.emit_spanned_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span }) } let tainted_by_errors = mbcx.emit_errors(); diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 3490c2dae5729..ff2196760039c 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -1,4 +1,3 @@ -use rustc_errors::MultiSpan; use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_middle::ty::Ty; use rustc_span::Span; @@ -101,7 +100,7 @@ pub(crate) struct LifeTimeOutLiveErr { #[primary_span] pub span: Span, #[subdiagnostic] - pub category: Option, + pub category: LifeTimeReturnCategoryErr, } #[derive(SessionSubdiagnostic)] @@ -123,12 +122,3 @@ pub(crate) enum LifeTimeReturnCategoryErr { outlived_fr_name: String, }, } - -#[derive(SessionSubdiagnostic)] -pub(crate) enum RequireStaticErr { - #[note(borrowck::used_impl_require_static)] - UsedImpl { - #[primary_span] - multi_span: MultiSpan, - }, -} diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index bea573b403bae..dbeaa564094f7 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -35,7 +35,6 @@ borrowck_var_cannot_escape_closure = .fr = inferred to be a `FnMut` closure .note = `FnMut` closures only have access to their captured variables while they are executing... - .note = `FnMut` closures only have access to their captured variables while they are executing... .cannot_escape = ...therefore, they cannot allow references to captured variables to escape borrowck_returned_closure_escaped = From 55d47effcfa6efd737ef0cb1cebfb803f6695597 Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Mon, 22 Aug 2022 20:37:40 +0800 Subject: [PATCH 10/10] sub diagnostic --- .../src/diagnostics/region_errors.rs | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 6894ec7956cfe..66b036d194af9 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -27,7 +27,7 @@ use rustc_span::Span; use crate::borrowck_errors; use crate::session_diagnostics::{ FnMutError, FnMutReturnTypeErr, GenericDoesNotLiveLongEnough, LifeTimeOutLiveErr, - LifeTimeReturnCategoryErr, + LifeTimeReturnCategoryErr, RequireStaticErr, }; use super::{OutlivesSuggestionBuilder, RegionName}; @@ -500,17 +500,17 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { debug!("report_fnmut_error: output_ty={:?}", output_ty); - let ty_err = match output_ty.kind() { - ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span }, - ty::Adt(def, _) if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) => { - FnMutReturnTypeErr::ReturnAsyncBlock { span: *span } - } - _ => FnMutReturnTypeErr::ReturnRef { span: *span }, - }; - let mut err = FnMutError { span: *span, - ty_err, + ty_err: match output_ty.kind() { + ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span }, + ty::Adt(def, _) + if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) => + { + FnMutReturnTypeErr::ReturnAsyncBlock { span: *span } + } + _ => FnMutReturnTypeErr::ReturnRef { span: *span }, + }, upvar_def_span: None, upvar_span: None, fr_span: None, @@ -682,6 +682,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let (_, mir_def_name) = self.infcx.tcx.article_and_description(self.mir_def_id().to_def_id()); + let mut err = LifeTimeOutLiveErr { span: *span, category: None }; + let fr_name = self.give_region_a_name(*fr).unwrap(); let outlived_fr_name = self.give_region_a_name(*outlived_fr).unwrap(); @@ -700,7 +702,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }, }; - let err = LifeTimeOutLiveErr { span: *span, category: err_category }; + err.category = Some(err_category); let mut diag = self.infcx.tcx.sess.create_err(err); @@ -854,7 +856,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ident.span, "calling this method introduces the `impl`'s 'static` requirement", ); - err.span_note(multi_span, "the used `impl` has a `'static` requirement"); + err.subdiagnostic(RequireStaticErr::UsedImpl { multi_span }); err.span_suggestion_verbose( span.shrink_to_hi(), "consider relaxing the implicit `'static` requirement",