diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index e0bd7a33f7373..061053ef2ac97 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1320,10 +1320,12 @@ impl<'a> Linker for WasmLd<'a> { // LLD will hide these otherwise-internal symbols since it only exports // symbols explicitly passed via the `--export` flags above and hides all - // others. Various bits and pieces of tooling use this, so be sure these - // symbols make their way out of the linker as well. - self.cmd.arg("--export=__heap_base"); - self.cmd.arg("--export=__data_end"); + // others. Various bits and pieces of wasm32-unknown-unknown tooling use + // this, so be sure these symbols make their way out of the linker as well. + if self.sess.target.os == "unknown" { + self.cmd.arg("--export=__heap_base"); + self.cmd.arg("--export=__data_end"); + } } fn subsystem(&mut self, _subsystem: &str) {} diff --git a/compiler/rustc_error_messages/locales/en-US/compiletest.ftl b/compiler/rustc_error_messages/locales/en-US/compiletest.ftl new file mode 100644 index 0000000000000..55061fbce7e4a --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/compiletest.ftl @@ -0,0 +1,5 @@ +compiletest_example = this is an example message used in testing + .note = with a note + .help = with a help + .suggestion = with a suggestion + .label = with a label diff --git a/compiler/rustc_error_messages/locales/en-US/typeck.ftl b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl similarity index 67% rename from compiler/rustc_error_messages/locales/en-US/typeck.ftl rename to compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl index 272731d9914cc..c6a4ff6f0e02f 100644 --- a/compiler/rustc_error_messages/locales/en-US/typeck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl @@ -1,101 +1,101 @@ -typeck_field_multiply_specified_in_initializer = +hir_analysis_field_multiply_specified_in_initializer = field `{$ident}` specified more than once .label = used more than once .previous_use_label = first use of `{$ident}` -typeck_unrecognized_atomic_operation = +hir_analysis_unrecognized_atomic_operation = unrecognized atomic operation function: `{$op}` .label = unrecognized atomic operation -typeck_wrong_number_of_generic_arguments_to_intrinsic = +hir_analysis_wrong_number_of_generic_arguments_to_intrinsic = intrinsic has wrong number of {$descr} parameters: found {$found}, expected {$expected} .label = expected {$expected} {$descr} {$expected -> [one] parameter *[other] parameters } -typeck_unrecognized_intrinsic_function = +hir_analysis_unrecognized_intrinsic_function = unrecognized intrinsic function: `{$name}` .label = unrecognized intrinsic -typeck_lifetimes_or_bounds_mismatch_on_trait = +hir_analysis_lifetimes_or_bounds_mismatch_on_trait = lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration .label = lifetimes do not match {$item_kind} in trait .generics_label = lifetimes in impl do not match this {$item_kind} in trait -typeck_drop_impl_on_wrong_item = +hir_analysis_drop_impl_on_wrong_item = the `Drop` trait may only be implemented for local structs, enums, and unions .label = must be a struct, enum, or union in the current crate -typeck_field_already_declared = +hir_analysis_field_already_declared = field `{$field_name}` is already declared .label = field already declared .previous_decl_label = `{$field_name}` first declared here -typeck_copy_impl_on_type_with_dtor = +hir_analysis_copy_impl_on_type_with_dtor = the trait `Copy` may not be implemented for this type; the type has a destructor .label = `Copy` not allowed on types with destructors -typeck_multiple_relaxed_default_bounds = +hir_analysis_multiple_relaxed_default_bounds = type parameter has more than one relaxed default bound, only one is supported -typeck_copy_impl_on_non_adt = +hir_analysis_copy_impl_on_non_adt = the trait `Copy` may not be implemented for this type .label = type is not a structure or enumeration -typeck_trait_object_declared_with_no_traits = +hir_analysis_trait_object_declared_with_no_traits = at least one trait is required for an object type .alias_span = this alias does not contain a trait -typeck_ambiguous_lifetime_bound = +hir_analysis_ambiguous_lifetime_bound = ambiguous lifetime bound, explicit lifetime bound required -typeck_assoc_type_binding_not_allowed = +hir_analysis_assoc_type_binding_not_allowed = associated type bindings are not allowed here .label = associated type not allowed here -typeck_functional_record_update_on_non_struct = +hir_analysis_functional_record_update_on_non_struct = functional record update syntax requires a struct -typeck_typeof_reserved_keyword_used = +hir_analysis_typeof_reserved_keyword_used = `typeof` is a reserved keyword but unimplemented .suggestion = consider replacing `typeof(...)` with an actual type .label = reserved keyword -typeck_return_stmt_outside_of_fn_body = +hir_analysis_return_stmt_outside_of_fn_body = return statement outside of function body .encl_body_label = the return is part of this body... .encl_fn_label = ...not the enclosing function body -typeck_yield_expr_outside_of_generator = +hir_analysis_yield_expr_outside_of_generator = yield expression outside of generator literal -typeck_struct_expr_non_exhaustive = +hir_analysis_struct_expr_non_exhaustive = cannot create non-exhaustive {$what} using struct expression -typeck_method_call_on_unknown_type = +hir_analysis_method_call_on_unknown_type = the type of this value must be known to call a method on a raw pointer on it -typeck_value_of_associated_struct_already_specified = +hir_analysis_value_of_associated_struct_already_specified = the value of the associated type `{$item_name}` (from trait `{$def_path}`) is already specified .label = re-bound here .previous_bound_label = `{$item_name}` bound here first -typeck_address_of_temporary_taken = cannot take address of a temporary +hir_analysis_address_of_temporary_taken = cannot take address of a temporary .label = temporary value -typeck_add_return_type_add = try adding a return type +hir_analysis_add_return_type_add = try adding a return type -typeck_add_return_type_missing_here = a return type might be missing here +hir_analysis_add_return_type_missing_here = a return type might be missing here -typeck_expected_default_return_type = expected `()` because of default return type +hir_analysis_expected_default_return_type = expected `()` because of default return type -typeck_expected_return_type = expected `{$expected}` because of return type +hir_analysis_expected_return_type = expected `{$expected}` because of return type -typeck_unconstrained_opaque_type = unconstrained opaque type +hir_analysis_unconstrained_opaque_type = unconstrained opaque type .note = `{$name}` must be used in combination with a concrete type within the same module -typeck_missing_type_params = +hir_analysis_missing_type_params = the type {$parameterCount -> [one] parameter *[other] parameters @@ -117,19 +117,19 @@ typeck_missing_type_params = } to {$parameters} .note = because of the default `Self` reference, type parameters must be specified on object types -typeck_manual_implementation = +hir_analysis_manual_implementation = manual implementations of `{$trait_name}` are experimental .label = manual implementations of `{$trait_name}` are experimental .help = add `#![feature(unboxed_closures)]` to the crate attributes to enable -typeck_substs_on_overridden_impl = could not resolve substs on overridden impl +hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl -typeck_unused_extern_crate = +hir_analysis_unused_extern_crate = unused extern crate .suggestion = remove it -typeck_extern_crate_not_idiomatic = +hir_analysis_extern_crate_not_idiomatic = `extern crate` is not idiomatic in the new edition .suggestion = convert it to a `{$msg_code}` -typeck_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` +hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index ff33ae7e8f224..2dc8a80cfc82e 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -40,27 +40,28 @@ fluent_messages! { attr => "../locales/en-US/attr.ftl", borrowck => "../locales/en-US/borrowck.ftl", builtin_macros => "../locales/en-US/builtin_macros.ftl", + compiletest => "../locales/en-US/compiletest.ftl", const_eval => "../locales/en-US/const_eval.ftl", driver => "../locales/en-US/driver.ftl", expand => "../locales/en-US/expand.ftl", - session => "../locales/en-US/session.ftl", - interface => "../locales/en-US/interface.ftl", + hir_analysis => "../locales/en-US/hir_analysis.ftl", infer => "../locales/en-US/infer.ftl", + interface => "../locales/en-US/interface.ftl", lint => "../locales/en-US/lint.ftl", + metadata => "../locales/en-US/metadata.ftl", middle => "../locales/en-US/middle.ftl", + mir_dataflow => "../locales/en-US/mir_dataflow.ftl", monomorphize => "../locales/en-US/monomorphize.ftl", - metadata => "../locales/en-US/metadata.ftl", parser => "../locales/en-US/parser.ftl", passes => "../locales/en-US/passes.ftl", plugin_impl => "../locales/en-US/plugin_impl.ftl", privacy => "../locales/en-US/privacy.ftl", query_system => "../locales/en-US/query_system.ftl", - trait_selection => "../locales/en-US/trait_selection.ftl", save_analysis => "../locales/en-US/save_analysis.ftl", - ty_utils => "../locales/en-US/ty_utils.ftl", - typeck => "../locales/en-US/typeck.ftl", - mir_dataflow => "../locales/en-US/mir_dataflow.ftl", + session => "../locales/en-US/session.ftl", symbol_mangling => "../locales/en-US/symbol_mangling.ftl", + trait_selection => "../locales/en-US/trait_selection.ftl", + ty_utils => "../locales/en-US/ty_utils.ftl", } pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES}; diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 24fb0b1fd26b5..f8a62c8491076 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -333,7 +333,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { find_opaque_ty_constraints_for_tait(tcx, def_id) } // Opaque types desugared from `impl Trait`. - ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), in_trait, .. }) => { + ItemKind::OpaqueTy(OpaqueTy { + origin: + hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), + in_trait, + .. + }) => { if in_trait { span_bug!(item.span, "impl-trait in trait has no default") } else { @@ -378,7 +383,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { Node::Field(field) => icx.to_ty(field.ty), - Node::Expr(&Expr { kind: ExprKind::Closure{..}, .. }) => tcx.typeck(def_id).node_type(hir_id), + Node::Expr(&Expr { kind: ExprKind::Closure { .. }, .. }) => { + tcx.typeck(def_id).node_type(hir_id) + } Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => { // We defer to `type_of` of the corresponding parameter @@ -410,40 +417,91 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) if asm.operands.iter().any(|(op, _op_sp)| match op { hir::InlineAsmOperand::Const { anon_const } - | hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id, + | hir::InlineAsmOperand::SymFn { anon_const } => { + anon_const.hir_id == hir_id + } _ => false, }) => { tcx.typeck(def_id).node_type(hir_id) } - Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => tcx - .adt_def(tcx.hir().get_parent_item(hir_id)) - .repr() - .discr_type() - .to_ty(tcx), + Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => { + tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx) + } - Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. }) - if let Node::TraitRef(trait_ref) = tcx.hir().get( - tcx.hir().get_parent_node(binding_id) - ) => + Node::TypeBinding( + binding @ &TypeBinding { + hir_id: binding_id, + kind: TypeBindingKind::Equality { term: Term::Const(ref e) }, + .. + }, + ) if let Node::TraitRef(trait_ref) = + tcx.hir().get(tcx.hir().get_parent_node(binding_id)) + && e.hir_id == hir_id => { - let Some(trait_def_id) = trait_ref.trait_def_id() else { - return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait"); - }; - let assoc_items = tcx.associated_items(trait_def_id); - let assoc_item = assoc_items.find_by_name_and_kind( - tcx, binding.ident, ty::AssocKind::Const, def_id.to_def_id(), - ); - if let Some(assoc_item) = assoc_item { - tcx.type_of(assoc_item.def_id) - } else { - // FIXME(associated_const_equality): add a useful error message here. - tcx.ty_error_with_message( - DUMMY_SP, - "Could not find associated const on trait", - ) - } + let Some(trait_def_id) = trait_ref.trait_def_id() else { + return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait"); + }; + let assoc_items = tcx.associated_items(trait_def_id); + let assoc_item = assoc_items.find_by_name_and_kind( + tcx, + binding.ident, + ty::AssocKind::Const, + def_id.to_def_id(), + ); + if let Some(assoc_item) = assoc_item { + tcx.type_of(assoc_item.def_id) + } else { + // FIXME(associated_const_equality): add a useful error message here. + tcx.ty_error_with_message( + DUMMY_SP, + "Could not find associated const on trait", + ) + } + } + + Node::TypeBinding( + binding @ &TypeBinding { hir_id: binding_id, gen_args, ref kind, .. }, + ) if let Node::TraitRef(trait_ref) = + tcx.hir().get(tcx.hir().get_parent_node(binding_id)) + && let Some((idx, _)) = + gen_args.args.iter().enumerate().find(|(_, arg)| { + if let GenericArg::Const(ct) = arg { + ct.value.hir_id == hir_id + } else { + false + } + }) => + { + let Some(trait_def_id) = trait_ref.trait_def_id() else { + return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait"); + }; + let assoc_items = tcx.associated_items(trait_def_id); + let assoc_item = assoc_items.find_by_name_and_kind( + tcx, + binding.ident, + match kind { + // I think `` type bindings requires that `A` is a type + TypeBindingKind::Constraint { .. } + | TypeBindingKind::Equality { term: Term::Ty(..) } => { + ty::AssocKind::Type + } + TypeBindingKind::Equality { term: Term::Const(..) } => { + ty::AssocKind::Const + } + }, + def_id.to_def_id(), + ); + if let Some(assoc_item) = assoc_item { + tcx.type_of(tcx.generics_of(assoc_item.def_id).params[idx].def_id) + } else { + // FIXME(associated_const_equality): add a useful error message here. + tcx.ty_error_with_message( + DUMMY_SP, + "Could not find associated const on trait", + ) + } } Node::GenericParam(&GenericParam { @@ -452,8 +510,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { .. }) if ct.hir_id == hir_id => tcx.type_of(tcx.hir().local_def_id(param_hir_id)), - x => - tcx.ty_error_with_message( + x => tcx.ty_error_with_message( DUMMY_SP, &format!("unexpected const parent in type_of(): {x:?}"), ), diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 44df47e2fa00c..d891171b82468 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1,4 +1,5 @@ -//! Errors emitted by typeck. +//! Errors emitted by `hir_analysis`. + use rustc_errors::IntoDiagnostic; use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; @@ -6,18 +7,18 @@ use rustc_middle::ty::Ty; use rustc_span::{symbol::Ident, Span, Symbol}; #[derive(Diagnostic)] -#[diag(typeck::field_multiply_specified_in_initializer, code = "E0062")] +#[diag(hir_analysis::field_multiply_specified_in_initializer, code = "E0062")] pub struct FieldMultiplySpecifiedInInitializer { #[primary_span] #[label] pub span: Span, - #[label(typeck::previous_use_label)] + #[label(hir_analysis::previous_use_label)] pub prev_span: Span, pub ident: Ident, } #[derive(Diagnostic)] -#[diag(typeck::unrecognized_atomic_operation, code = "E0092")] +#[diag(hir_analysis::unrecognized_atomic_operation, code = "E0092")] pub struct UnrecognizedAtomicOperation<'a> { #[primary_span] #[label] @@ -26,7 +27,7 @@ pub struct UnrecognizedAtomicOperation<'a> { } #[derive(Diagnostic)] -#[diag(typeck::wrong_number_of_generic_arguments_to_intrinsic, code = "E0094")] +#[diag(hir_analysis::wrong_number_of_generic_arguments_to_intrinsic, code = "E0094")] pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> { #[primary_span] #[label] @@ -37,7 +38,7 @@ pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> { } #[derive(Diagnostic)] -#[diag(typeck::unrecognized_intrinsic_function, code = "E0093")] +#[diag(hir_analysis::unrecognized_intrinsic_function, code = "E0093")] pub struct UnrecognizedIntrinsicFunction { #[primary_span] #[label] @@ -46,19 +47,19 @@ pub struct UnrecognizedIntrinsicFunction { } #[derive(Diagnostic)] -#[diag(typeck::lifetimes_or_bounds_mismatch_on_trait, code = "E0195")] +#[diag(hir_analysis::lifetimes_or_bounds_mismatch_on_trait, code = "E0195")] pub struct LifetimesOrBoundsMismatchOnTrait { #[primary_span] #[label] pub span: Span, - #[label(typeck::generics_label)] + #[label(hir_analysis::generics_label)] pub generics_span: Option, pub item_kind: &'static str, pub ident: Ident, } #[derive(Diagnostic)] -#[diag(typeck::drop_impl_on_wrong_item, code = "E0120")] +#[diag(hir_analysis::drop_impl_on_wrong_item, code = "E0120")] pub struct DropImplOnWrongItem { #[primary_span] #[label] @@ -66,18 +67,18 @@ pub struct DropImplOnWrongItem { } #[derive(Diagnostic)] -#[diag(typeck::field_already_declared, code = "E0124")] +#[diag(hir_analysis::field_already_declared, code = "E0124")] pub struct FieldAlreadyDeclared { pub field_name: Ident, #[primary_span] #[label] pub span: Span, - #[label(typeck::previous_decl_label)] + #[label(hir_analysis::previous_decl_label)] pub prev_span: Span, } #[derive(Diagnostic)] -#[diag(typeck::copy_impl_on_type_with_dtor, code = "E0184")] +#[diag(hir_analysis::copy_impl_on_type_with_dtor, code = "E0184")] pub struct CopyImplOnTypeWithDtor { #[primary_span] #[label] @@ -85,14 +86,14 @@ pub struct CopyImplOnTypeWithDtor { } #[derive(Diagnostic)] -#[diag(typeck::multiple_relaxed_default_bounds, code = "E0203")] +#[diag(hir_analysis::multiple_relaxed_default_bounds, code = "E0203")] pub struct MultipleRelaxedDefaultBounds { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(typeck::copy_impl_on_non_adt, code = "E0206")] +#[diag(hir_analysis::copy_impl_on_non_adt, code = "E0206")] pub struct CopyImplOnNonAdt { #[primary_span] #[label] @@ -100,23 +101,23 @@ pub struct CopyImplOnNonAdt { } #[derive(Diagnostic)] -#[diag(typeck::trait_object_declared_with_no_traits, code = "E0224")] +#[diag(hir_analysis::trait_object_declared_with_no_traits, code = "E0224")] pub struct TraitObjectDeclaredWithNoTraits { #[primary_span] pub span: Span, - #[label(typeck::alias_span)] + #[label(hir_analysis::alias_span)] pub trait_alias_span: Option, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0227")] +#[diag(hir_analysis::ambiguous_lifetime_bound, code = "E0227")] pub struct AmbiguousLifetimeBound { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(typeck::assoc_type_binding_not_allowed, code = "E0229")] +#[diag(hir_analysis::assoc_type_binding_not_allowed, code = "E0229")] pub struct AssocTypeBindingNotAllowed { #[primary_span] #[label] @@ -124,14 +125,14 @@ pub struct AssocTypeBindingNotAllowed { } #[derive(Diagnostic)] -#[diag(typeck::functional_record_update_on_non_struct, code = "E0436")] +#[diag(hir_analysis::functional_record_update_on_non_struct, code = "E0436")] pub struct FunctionalRecordUpdateOnNonStruct { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(typeck::typeof_reserved_keyword_used, code = "E0516")] +#[diag(hir_analysis::typeof_reserved_keyword_used, code = "E0516")] pub struct TypeofReservedKeywordUsed<'tcx> { pub ty: Ty<'tcx>, #[primary_span] @@ -142,25 +143,25 @@ pub struct TypeofReservedKeywordUsed<'tcx> { } #[derive(Diagnostic)] -#[diag(typeck::return_stmt_outside_of_fn_body, code = "E0572")] +#[diag(hir_analysis::return_stmt_outside_of_fn_body, code = "E0572")] pub struct ReturnStmtOutsideOfFnBody { #[primary_span] pub span: Span, - #[label(typeck::encl_body_label)] + #[label(hir_analysis::encl_body_label)] pub encl_body_span: Option, - #[label(typeck::encl_fn_label)] + #[label(hir_analysis::encl_fn_label)] pub encl_fn_span: Option, } #[derive(Diagnostic)] -#[diag(typeck::yield_expr_outside_of_generator, code = "E0627")] +#[diag(hir_analysis::yield_expr_outside_of_generator, code = "E0627")] pub struct YieldExprOutsideOfGenerator { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(typeck::struct_expr_non_exhaustive, code = "E0639")] +#[diag(hir_analysis::struct_expr_non_exhaustive, code = "E0639")] pub struct StructExprNonExhaustive { #[primary_span] pub span: Span, @@ -168,26 +169,26 @@ pub struct StructExprNonExhaustive { } #[derive(Diagnostic)] -#[diag(typeck::method_call_on_unknown_type, code = "E0699")] +#[diag(hir_analysis::method_call_on_unknown_type, code = "E0699")] pub struct MethodCallOnUnknownType { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(typeck::value_of_associated_struct_already_specified, code = "E0719")] +#[diag(hir_analysis::value_of_associated_struct_already_specified, code = "E0719")] pub struct ValueOfAssociatedStructAlreadySpecified { #[primary_span] #[label] pub span: Span, - #[label(typeck::previous_bound_label)] + #[label(hir_analysis::previous_bound_label)] pub prev_span: Span, pub item_name: Ident, pub def_path: String, } #[derive(Diagnostic)] -#[diag(typeck::address_of_temporary_taken, code = "E0745")] +#[diag(hir_analysis::address_of_temporary_taken, code = "E0745")] pub struct AddressOfTemporaryTaken { #[primary_span] #[label] @@ -197,7 +198,7 @@ pub struct AddressOfTemporaryTaken { #[derive(Subdiagnostic)] pub enum AddReturnTypeSuggestion { #[suggestion( - typeck::add_return_type_add, + hir_analysis::add_return_type_add, code = "-> {found} ", applicability = "machine-applicable" )] @@ -207,7 +208,7 @@ pub enum AddReturnTypeSuggestion { found: String, }, #[suggestion( - typeck::add_return_type_missing_here, + hir_analysis::add_return_type_missing_here, code = "-> _ ", applicability = "has-placeholders" )] @@ -219,12 +220,12 @@ pub enum AddReturnTypeSuggestion { #[derive(Subdiagnostic)] pub enum ExpectedReturnTypeLabel<'tcx> { - #[label(typeck::expected_default_return_type)] + #[label(hir_analysis::expected_default_return_type)] Unit { #[primary_span] span: Span, }, - #[label(typeck::expected_return_type)] + #[label(hir_analysis::expected_return_type)] Other { #[primary_span] span: Span, @@ -233,7 +234,7 @@ pub enum ExpectedReturnTypeLabel<'tcx> { } #[derive(Diagnostic)] -#[diag(typeck::unconstrained_opaque_type)] +#[diag(hir_analysis::unconstrained_opaque_type)] #[note] pub struct UnconstrainedOpaqueType { #[primary_span] @@ -254,7 +255,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams { fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let mut err = handler.struct_span_err_with_code( self.span, - rustc_errors::fluent::typeck::missing_type_params, + rustc_errors::fluent::hir_analysis::missing_type_params, error_code!(E0393), ); err.set_arg("parameterCount", self.missing_type_params.len()); @@ -267,7 +268,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams { .join(", "), ); - err.span_label(self.def_span, rustc_errors::fluent::typeck::label); + err.span_label(self.def_span, rustc_errors::fluent::hir_analysis::label); let mut suggested = false; // Don't suggest setting the type params if there are some already: the order is @@ -282,7 +283,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams { // least we can clue them to the correct syntax `Iterator`. err.span_suggestion( self.span, - rustc_errors::fluent::typeck::suggestion, + rustc_errors::fluent::hir_analysis::suggestion, format!( "{}<{}>", snippet, @@ -298,16 +299,16 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams { } } if !suggested { - err.span_label(self.span, rustc_errors::fluent::typeck::no_suggestion_label); + err.span_label(self.span, rustc_errors::fluent::hir_analysis::no_suggestion_label); } - err.note(rustc_errors::fluent::typeck::note); + err.note(rustc_errors::fluent::hir_analysis::note); err } } #[derive(Diagnostic)] -#[diag(typeck::manual_implementation, code = "E0183")] +#[diag(hir_analysis::manual_implementation, code = "E0183")] #[help] pub struct ManualImplementation { #[primary_span] @@ -317,21 +318,21 @@ pub struct ManualImplementation { } #[derive(Diagnostic)] -#[diag(typeck::substs_on_overridden_impl)] +#[diag(hir_analysis::substs_on_overridden_impl)] pub struct SubstsOnOverriddenImpl { #[primary_span] pub span: Span, } #[derive(LintDiagnostic)] -#[diag(typeck::unused_extern_crate)] +#[diag(hir_analysis::unused_extern_crate)] pub struct UnusedExternCrate { #[suggestion(applicability = "machine-applicable", code = "")] pub span: Span, } #[derive(LintDiagnostic)] -#[diag(typeck::extern_crate_not_idiomatic)] +#[diag(hir_analysis::extern_crate_not_idiomatic)] pub struct ExternCrateNotIdiomatic { #[suggestion_short(applicability = "machine-applicable", code = "{suggestion_code}")] pub span: Span, @@ -340,7 +341,7 @@ pub struct ExternCrateNotIdiomatic { } #[derive(Diagnostic)] -#[diag(typeck::expected_used_symbol)] +#[diag(hir_analysis::expected_used_symbol)] pub struct ExpectedUsedSymbol { #[primary_span] pub span: Span, diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index b9a283552f75f..278495f555547 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -36,7 +36,7 @@ impl<'a> DiagnosticDerive<'a> { span_err(builder.span, "diagnostic slug not specified") .help(&format!( "specify the slug as the first argument to the `#[diag(...)]` \ - attribute, such as `#[diag(typeck::example_error)]`", + attribute, such as `#[diag(hir_analysis::example_error)]`", )) .emit(); return DiagnosticDeriveError::ErrorHandled.to_compile_error(); @@ -101,7 +101,7 @@ impl<'a> LintDiagnosticDerive<'a> { span_err(builder.span, "diagnostic slug not specified") .help(&format!( "specify the slug as the first argument to the attribute, such as \ - `#[diag(typeck::example_error)]`", + `#[diag(hir_analysis::example_error)]`", )) .emit(); return DiagnosticDeriveError::ErrorHandled.to_compile_error(); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 3c276a9ada97b..824cebd7e0a5b 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -130,6 +130,16 @@ pub(super) enum LifetimeElisionCandidate { Missing(MissingLifetime), } +/// Only used for diagnostics. +struct BaseError { + msg: String, + fallback_label: String, + span: Span, + span_label: Option<(Span, &'static str)>, + could_be_expr: bool, + suggestion: Option<(Span, &'static str, String)>, +} + impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { fn def_span(&self, def_id: DefId) -> Option { match def_id.krate { @@ -138,35 +148,18 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } } - /// Handles error reporting for `smart_resolve_path_fragment` function. - /// Creates base error and amends it with one short label and possibly some longer helps/notes. - pub(crate) fn smart_resolve_report_errors( + fn make_base_error( &mut self, path: &[Segment], span: Span, source: PathSource<'_>, res: Option, - ) -> (DiagnosticBuilder<'a, ErrorGuaranteed>, Vec) { - let ident_span = path.last().map_or(span, |ident| ident.ident.span); - let ns = source.namespace(); - let is_expected = &|res| source.is_expected(res); - let is_enum_variant = &|res| matches!(res, Res::Def(DefKind::Variant, _)); - - debug!(?res, ?source); - + ) -> BaseError { // Make the base error. - struct BaseError<'a> { - msg: String, - fallback_label: String, - span: Span, - span_label: Option<(Span, &'a str)>, - could_be_expr: bool, - suggestion: Option<(Span, &'a str, String)>, - } let mut expected = source.descr_expected(); let path_str = Segment::names_to_string(path); let item_str = path.last().unwrap().ident; - let base_error = if let Some(res) = res { + if let Some(res) = res { BaseError { msg: format!("expected {}, found {} `{}`", expected, res.descr(), path_str), fallback_label: format!("not a {expected}"), @@ -277,8 +270,20 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { could_be_expr: false, suggestion, } - }; + } + } + /// Handles error reporting for `smart_resolve_path_fragment` function. + /// Creates base error and amends it with one short label and possibly some longer helps/notes. + pub(crate) fn smart_resolve_report_errors( + &mut self, + path: &[Segment], + span: Span, + source: PathSource<'_>, + res: Option, + ) -> (DiagnosticBuilder<'a, ErrorGuaranteed>, Vec) { + debug!(?res, ?source); + let base_error = self.make_base_error(path, span, source, res); let code = source.error_code(res.is_some()); let mut err = self.r.session.struct_span_err_with_code(base_error.span, &base_error.msg, code); @@ -289,41 +294,79 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_label(span, label); } - if let Some(sugg) = base_error.suggestion { - err.span_suggestion_verbose(sugg.0, sugg.1, sugg.2, Applicability::MaybeIncorrect); + if let Some(ref sugg) = base_error.suggestion { + err.span_suggestion_verbose(sugg.0, sugg.1, &sugg.2, Applicability::MaybeIncorrect); } - if let Some(span) = self.diagnostic_metadata.current_block_could_be_bare_struct_literal { - err.multipart_suggestion( - "you might have meant to write a `struct` literal", - vec![ - (span.shrink_to_lo(), "{ SomeStruct ".to_string()), - (span.shrink_to_hi(), "}".to_string()), - ], - Applicability::HasPlaceholders, - ); + self.suggest_bare_struct_literal(&mut err); + self.suggest_pattern_match_with_let(&mut err, source, span); + + self.suggest_self_or_self_ref(&mut err, path, span); + self.detect_assoct_type_constraint_meant_as_path(&mut err, &base_error); + if self.suggest_self_ty(&mut err, source, path, span) + || self.suggest_self_value(&mut err, source, path, span) + { + return (err, Vec::new()); } - match (source, self.diagnostic_metadata.in_if_condition) { - ( - PathSource::Expr(_), - Some(Expr { span: expr_span, kind: ExprKind::Assign(lhs, _, _), .. }), - ) => { - // Icky heuristic so we don't suggest: - // `if (i + 2) = 2` => `if let (i + 2) = 2` (approximately pattern) - // `if 2 = i` => `if let 2 = i` (lhs needs to contain error span) - if lhs.is_approximately_pattern() && lhs.span.contains(span) { - err.span_suggestion_verbose( - expr_span.shrink_to_lo(), - "you might have meant to use pattern matching", - "let ", - Applicability::MaybeIncorrect, - ); + + let (found, candidates) = + self.try_lookup_name_relaxed(&mut err, source, path, span, res, &base_error); + if found { + return (err, candidates); + } + + if !self.type_ascription_suggestion(&mut err, base_error.span) { + let mut fallback = + self.suggest_trait_and_bounds(&mut err, source, res, span, &base_error); + fallback |= self.suggest_typo(&mut err, source, path, span, &base_error); + if fallback { + // Fallback label. + err.span_label(base_error.span, &base_error.fallback_label); + } + } + self.err_code_special_cases(&mut err, source, path, span); + + (err, candidates) + } + + fn detect_assoct_type_constraint_meant_as_path( + &self, + err: &mut Diagnostic, + base_error: &BaseError, + ) { + let Some(ty) = self.diagnostic_metadata.current_type_path else { return; }; + let TyKind::Path(_, path) = &ty.kind else { return; }; + for segment in &path.segments { + let Some(params) = &segment.args else { continue; }; + let ast::GenericArgs::AngleBracketed(ref params) = params.deref() else { continue; }; + for param in ¶ms.args { + let ast::AngleBracketedArg::Constraint(constraint) = param else { continue; }; + let ast::AssocConstraintKind::Bound { bounds } = &constraint.kind else { + continue; + }; + for bound in bounds { + let ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifier::None) + = bound else + { + continue; + }; + if base_error.span == trait_ref.span { + err.span_suggestion_verbose( + constraint.ident.span.between(trait_ref.span), + "you might have meant to write a path instead of an associated type bound", + "::", + Applicability::MachineApplicable, + ); + } } } - _ => {} } + } + fn suggest_self_or_self_ref(&mut self, err: &mut Diagnostic, path: &[Segment], span: Span) { let is_assoc_fn = self.self_type_is_available(); + let Some(path_last_segment) = path.last() else { return }; + let item_str = path_last_segment.ident; // Emit help message for fake-self from other languages (e.g., `this` in Javascript). if ["this", "my"].contains(&item_str.as_str()) && is_assoc_fn { err.span_suggestion_short( @@ -358,96 +401,25 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } } } + } - self.detect_assoct_type_constraint_meant_as_path(base_error.span, &mut err); - - // Emit special messages for unresolved `Self` and `self`. - if is_self_type(path, ns) { - err.code(rustc_errors::error_code!(E0411)); - err.span_label( - span, - "`Self` is only available in impls, traits, and type definitions".to_string(), - ); - if let Some(item_kind) = self.diagnostic_metadata.current_item { - err.span_label( - item_kind.ident.span, - format!( - "`Self` not allowed in {} {}", - item_kind.kind.article(), - item_kind.kind.descr() - ), - ); - } - return (err, Vec::new()); - } - if is_self_value(path, ns) { - debug!("smart_resolve_path_fragment: E0424, source={:?}", source); - - err.code(rustc_errors::error_code!(E0424)); - err.span_label(span, match source { - PathSource::Pat => "`self` value is a keyword and may not be bound to variables or shadowed", - _ => "`self` value is a keyword only available in methods with a `self` parameter", - }); - if let Some((fn_kind, span)) = &self.diagnostic_metadata.current_function { - // The current function has a `self' parameter, but we were unable to resolve - // a reference to `self`. This can only happen if the `self` identifier we - // are resolving came from a different hygiene context. - if fn_kind.decl().inputs.get(0).map_or(false, |p| p.is_self()) { - err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters"); - } else { - let doesnt = if is_assoc_fn { - let (span, sugg) = fn_kind - .decl() - .inputs - .get(0) - .map(|p| (p.span.shrink_to_lo(), "&self, ")) - .unwrap_or_else(|| { - // Try to look for the "(" after the function name, if possible. - // This avoids placing the suggestion into the visibility specifier. - let span = fn_kind - .ident() - .map_or(*span, |ident| span.with_lo(ident.span.hi())); - ( - self.r - .session - .source_map() - .span_through_char(span, '(') - .shrink_to_hi(), - "&self", - ) - }); - err.span_suggestion_verbose( - span, - "add a `self` receiver parameter to make the associated `fn` a method", - sugg, - Applicability::MaybeIncorrect, - ); - "doesn't" - } else { - "can't" - }; - if let Some(ident) = fn_kind.ident() { - err.span_label( - ident.span, - &format!("this function {} have a `self` parameter", doesnt), - ); - } - } - } else if let Some(item_kind) = self.diagnostic_metadata.current_item { - err.span_label( - item_kind.ident.span, - format!( - "`self` not allowed in {} {}", - item_kind.kind.article(), - item_kind.kind.descr() - ), - ); - } - return (err, Vec::new()); - } - + fn try_lookup_name_relaxed( + &mut self, + err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + source: PathSource<'_>, + path: &[Segment], + span: Span, + res: Option, + base_error: &BaseError, + ) -> (bool, Vec) { // Try to lookup name in more relaxed fashion for better error reporting. let ident = path.last().unwrap().ident; + let is_expected = &|res| source.is_expected(res); + let ns = source.namespace(); + let is_enum_variant = &|res| matches!(res, Res::Def(DefKind::Variant, _)); + let path_str = Segment::names_to_string(path); + let ident_span = path.last().map_or(span, |ident| ident.ident.span); + let mut candidates = self .r .lookup_import_candidates(ident, ns, &self.parent_scope, is_expected) @@ -494,7 +466,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { { // Already reported this issue on the lhs of the type ascription. err.delay_as_bug(); - return (err, candidates); + return (true, candidates); } } @@ -522,8 +494,9 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { ); } } + // Try Levenshtein algorithm. - let typo_sugg = self.lookup_typo_candidate(path, ns, is_expected); + let typo_sugg = self.lookup_typo_candidate(path, source.namespace(), is_expected); if path.len() == 1 && self.self_type_is_available() { if let Some(candidate) = self.lookup_assoc_candidate(ident, ns, is_expected) { let self_is_available = self.self_value_is_available(path[0].ident.span); @@ -560,8 +533,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { ); } } - self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span); - return (err, candidates); + self.r.add_typo_suggestion(err, typo_sugg, ident_span); + return (true, candidates); } // If the first argument in call is `self` suggest calling a method. @@ -579,14 +552,14 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { format!("self.{path_str}({args_snippet})"), Applicability::MachineApplicable, ); - return (err, candidates); + return (true, candidates); } } // Try context-dependent help if relaxed lookup didn't work. if let Some(res) = res { if self.smart_resolve_context_dependent_help( - &mut err, + err, span, source, res, @@ -594,106 +567,135 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { &base_error.fallback_label, ) { // We do this to avoid losing a secondary span when we override the main error span. - self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span); - return (err, candidates); + self.r.add_typo_suggestion(err, typo_sugg, ident_span); + return (true, candidates); } } + return (false, candidates); + } + fn suggest_trait_and_bounds( + &mut self, + err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + source: PathSource<'_>, + res: Option, + span: Span, + base_error: &BaseError, + ) -> bool { let is_macro = base_error.span.from_expansion() && base_error.span.desugaring_kind().is_none(); - if !self.type_ascription_suggestion(&mut err, base_error.span) { - let mut fallback = false; - if let ( - PathSource::Trait(AliasPossibility::Maybe), - Some(Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)), - false, - ) = (source, res, is_macro) - { - if let Some(bounds @ [_, .., _]) = self.diagnostic_metadata.current_trait_object { - fallback = true; - let spans: Vec = bounds - .iter() - .map(|bound| bound.span()) - .filter(|&sp| sp != base_error.span) - .collect(); + let mut fallback = false; - let start_span = bounds[0].span(); - // `end_span` is the end of the poly trait ref (Foo + 'baz + Bar><) - let end_span = bounds.last().unwrap().span(); - // `last_bound_span` is the last bound of the poly trait ref (Foo + >'baz< + Bar) - let last_bound_span = spans.last().cloned().unwrap(); - let mut multi_span: MultiSpan = spans.clone().into(); - for sp in spans { - let msg = if sp == last_bound_span { - format!( - "...because of {these} bound{s}", - these = pluralize!("this", bounds.len() - 1), - s = pluralize!(bounds.len() - 1), - ) - } else { - String::new() - }; - multi_span.push_span_label(sp, msg); - } - multi_span - .push_span_label(base_error.span, "expected this type to be a trait..."); - err.span_help( - multi_span, - "`+` is used to constrain a \"trait object\" type with lifetimes or \ - auto-traits; structs and enums can't be bound in that way", - ); - if bounds.iter().all(|bound| match bound { - ast::GenericBound::Outlives(_) => true, - ast::GenericBound::Trait(tr, _) => tr.span == base_error.span, - }) { - let mut sugg = vec![]; - if base_error.span != start_span { - sugg.push((start_span.until(base_error.span), String::new())); - } - if base_error.span != end_span { - sugg.push((base_error.span.shrink_to_hi().to(end_span), String::new())); - } + if let ( + PathSource::Trait(AliasPossibility::Maybe), + Some(Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)), + false, + ) = (source, res, is_macro) + { + if let Some(bounds @ [_, .., _]) = self.diagnostic_metadata.current_trait_object { + fallback = true; + let spans: Vec = bounds + .iter() + .map(|bound| bound.span()) + .filter(|&sp| sp != base_error.span) + .collect(); - err.multipart_suggestion( - "if you meant to use a type and not a trait here, remove the bounds", - sugg, - Applicability::MaybeIncorrect, - ); + let start_span = bounds[0].span(); + // `end_span` is the end of the poly trait ref (Foo + 'baz + Bar><) + let end_span = bounds.last().unwrap().span(); + // `last_bound_span` is the last bound of the poly trait ref (Foo + >'baz< + Bar) + let last_bound_span = spans.last().cloned().unwrap(); + let mut multi_span: MultiSpan = spans.clone().into(); + for sp in spans { + let msg = if sp == last_bound_span { + format!( + "...because of {these} bound{s}", + these = pluralize!("this", bounds.len() - 1), + s = pluralize!(bounds.len() - 1), + ) + } else { + String::new() + }; + multi_span.push_span_label(sp, msg); + } + multi_span.push_span_label(base_error.span, "expected this type to be a trait..."); + err.span_help( + multi_span, + "`+` is used to constrain a \"trait object\" type with lifetimes or \ + auto-traits; structs and enums can't be bound in that way", + ); + if bounds.iter().all(|bound| match bound { + ast::GenericBound::Outlives(_) => true, + ast::GenericBound::Trait(tr, _) => tr.span == base_error.span, + }) { + let mut sugg = vec![]; + if base_error.span != start_span { + sugg.push((start_span.until(base_error.span), String::new())); } + if base_error.span != end_span { + sugg.push((base_error.span.shrink_to_hi().to(end_span), String::new())); + } + + err.multipart_suggestion( + "if you meant to use a type and not a trait here, remove the bounds", + sugg, + Applicability::MaybeIncorrect, + ); } } + } - fallback |= self.restrict_assoc_type_in_where_clause(span, &mut err); + fallback |= self.restrict_assoc_type_in_where_clause(span, err); + fallback + } - if !self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span) { - fallback = true; - match self.diagnostic_metadata.current_let_binding { - Some((pat_sp, Some(ty_sp), None)) - if ty_sp.contains(base_error.span) && base_error.could_be_expr => - { - err.span_suggestion_short( - pat_sp.between(ty_sp), - "use `=` if you meant to assign", - " = ", - Applicability::MaybeIncorrect, - ); - } - _ => {} + fn suggest_typo( + &mut self, + err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + source: PathSource<'_>, + path: &[Segment], + span: Span, + base_error: &BaseError, + ) -> bool { + let is_expected = &|res| source.is_expected(res); + let ident_span = path.last().map_or(span, |ident| ident.ident.span); + let typo_sugg = self.lookup_typo_candidate(path, source.namespace(), is_expected); + let mut fallback = false; + if !self.r.add_typo_suggestion(err, typo_sugg, ident_span) { + fallback = true; + match self.diagnostic_metadata.current_let_binding { + Some((pat_sp, Some(ty_sp), None)) + if ty_sp.contains(base_error.span) && base_error.could_be_expr => + { + err.span_suggestion_short( + pat_sp.between(ty_sp), + "use `=` if you meant to assign", + " = ", + Applicability::MaybeIncorrect, + ); } - - // If the trait has a single item (which wasn't matched by Levenshtein), suggest it - let suggestion = self.get_single_associated_item(&path, &source, is_expected); - self.r.add_typo_suggestion(&mut err, suggestion, ident_span); - } - if fallback { - // Fallback label. - err.span_label(base_error.span, base_error.fallback_label); + _ => {} } + + // If the trait has a single item (which wasn't matched by Levenshtein), suggest it + let suggestion = self.get_single_associated_item(&path, &source, is_expected); + self.r.add_typo_suggestion(err, suggestion, ident_span); } + fallback + } + + fn err_code_special_cases( + &mut self, + err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + source: PathSource<'_>, + path: &[Segment], + span: Span, + ) { if let Some(err_code) = &err.code { if err_code == &rustc_errors::error_code!(E0425) { for label_rib in &self.label_ribs { for (label_ident, node_id) in &label_rib.bindings { + let ident = path.last().unwrap().ident; if format!("'{}", ident) == label_ident.to_string() { err.span_label(label_ident.span, "a label with a similar name exists"); if let PathSource::Expr(Some(Expr { @@ -724,38 +726,116 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } } } + } - (err, candidates) + /// Emit special messages for unresolved `Self` and `self`. + fn suggest_self_ty( + &mut self, + err: &mut Diagnostic, + source: PathSource<'_>, + path: &[Segment], + span: Span, + ) -> bool { + if !is_self_type(path, source.namespace()) { + return false; + } + err.code(rustc_errors::error_code!(E0411)); + err.span_label( + span, + "`Self` is only available in impls, traits, and type definitions".to_string(), + ); + if let Some(item_kind) = self.diagnostic_metadata.current_item { + err.span_label( + item_kind.ident.span, + format!( + "`Self` not allowed in {} {}", + item_kind.kind.article(), + item_kind.kind.descr() + ), + ); + } + true } - fn detect_assoct_type_constraint_meant_as_path(&self, base_span: Span, err: &mut Diagnostic) { - let Some(ty) = self.diagnostic_metadata.current_type_path else { return; }; - let TyKind::Path(_, path) = &ty.kind else { return; }; - for segment in &path.segments { - let Some(params) = &segment.args else { continue; }; - let ast::GenericArgs::AngleBracketed(ref params) = params.deref() else { continue; }; - for param in ¶ms.args { - let ast::AngleBracketedArg::Constraint(constraint) = param else { continue; }; - let ast::AssocConstraintKind::Bound { bounds } = &constraint.kind else { - continue; + fn suggest_self_value( + &mut self, + err: &mut Diagnostic, + source: PathSource<'_>, + path: &[Segment], + span: Span, + ) -> bool { + if !is_self_value(path, source.namespace()) { + return false; + } + + debug!("smart_resolve_path_fragment: E0424, source={:?}", source); + err.code(rustc_errors::error_code!(E0424)); + err.span_label( + span, + match source { + PathSource::Pat => { + "`self` value is a keyword and may not be bound to variables or shadowed" + } + _ => "`self` value is a keyword only available in methods with a `self` parameter", + }, + ); + let is_assoc_fn = self.self_type_is_available(); + if let Some((fn_kind, span)) = &self.diagnostic_metadata.current_function { + // The current function has a `self' parameter, but we were unable to resolve + // a reference to `self`. This can only happen if the `self` identifier we + // are resolving came from a different hygiene context. + if fn_kind.decl().inputs.get(0).map_or(false, |p| p.is_self()) { + err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters"); + } else { + let doesnt = if is_assoc_fn { + let (span, sugg) = fn_kind + .decl() + .inputs + .get(0) + .map(|p| (p.span.shrink_to_lo(), "&self, ")) + .unwrap_or_else(|| { + // Try to look for the "(" after the function name, if possible. + // This avoids placing the suggestion into the visibility specifier. + let span = fn_kind + .ident() + .map_or(*span, |ident| span.with_lo(ident.span.hi())); + ( + self.r + .session + .source_map() + .span_through_char(span, '(') + .shrink_to_hi(), + "&self", + ) + }); + err.span_suggestion_verbose( + span, + "add a `self` receiver parameter to make the associated `fn` a method", + sugg, + Applicability::MaybeIncorrect, + ); + "doesn't" + } else { + "can't" }; - for bound in bounds { - let ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifier::None) - = bound else - { - continue; - }; - if base_span == trait_ref.span { - err.span_suggestion_verbose( - constraint.ident.span.between(trait_ref.span), - "you might have meant to write a path instead of an associated type bound", - "::", - Applicability::MachineApplicable, - ); - } + if let Some(ident) = fn_kind.ident() { + err.span_label( + ident.span, + &format!("this function {} have a `self` parameter", doesnt), + ); } } + } else if let Some(item_kind) = self.diagnostic_metadata.current_item { + err.span_label( + item_kind.ident.span, + format!( + "`self` not allowed in {} {}", + item_kind.kind.article(), + item_kind.kind.descr() + ), + ); } + true } fn suggest_swapping_misplaced_self_ty_and_trait( @@ -787,6 +867,45 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } } + fn suggest_bare_struct_literal(&mut self, err: &mut Diagnostic) { + if let Some(span) = self.diagnostic_metadata.current_block_could_be_bare_struct_literal { + err.multipart_suggestion( + "you might have meant to write a `struct` literal", + vec![ + (span.shrink_to_lo(), "{ SomeStruct ".to_string()), + (span.shrink_to_hi(), "}".to_string()), + ], + Applicability::HasPlaceholders, + ); + } + } + + fn suggest_pattern_match_with_let( + &mut self, + err: &mut Diagnostic, + source: PathSource<'_>, + span: Span, + ) { + if let PathSource::Expr(_) = source && + let Some(Expr { + span: expr_span, + kind: ExprKind::Assign(lhs, _, _), + .. + }) = self.diagnostic_metadata.in_if_condition { + // Icky heuristic so we don't suggest: + // `if (i + 2) = 2` => `if let (i + 2) = 2` (approximately pattern) + // `if 2 = i` => `if let 2 = i` (lhs needs to contain error span) + if lhs.is_approximately_pattern() && lhs.span.contains(span) { + err.span_suggestion_verbose( + expr_span.shrink_to_lo(), + "you might have meant to use pattern matching", + "let ", + Applicability::MaybeIncorrect, + ); + } + } + } + fn get_single_associated_item( &mut self, path: &[Segment], diff --git a/library/std/src/os/fd/mod.rs b/library/std/src/os/fd/mod.rs index a456947534a45..c6aa7c77dbc41 100644 --- a/library/std/src/os/fd/mod.rs +++ b/library/std/src/os/fd/mod.rs @@ -1,16 +1,25 @@ //! Owned and borrowed Unix-like file descriptors. +//! +//! This module is supported on Unix platforms and WASI, which both use a +//! similar file descriptor system for referencing OS resources. #![stable(feature = "io_safety", since = "1.63.0")] #![deny(unsafe_op_in_unsafe_fn)] // `RawFd`, `AsRawFd`, etc. -pub mod raw; +mod raw; // `OwnedFd`, `AsFd`, etc. -pub mod owned; +mod owned; // Implementations for `AsRawFd` etc. for network types. mod net; #[cfg(test)] mod tests; + +// Export the types and traits for the public API. +#[unstable(feature = "os_fd", issue = "98699")] +pub use owned::*; +#[unstable(feature = "os_fd", issue = "98699")] +pub use raw::*; diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 71e33fb9ed864..9875c389d8aaf 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -206,10 +206,8 @@ pub trait AsFd { /// ```rust,no_run /// use std::fs::File; /// # use std::io; - /// # #[cfg(target_os = "wasi")] - /// # use std::os::wasi::io::{AsFd, BorrowedFd}; - /// # #[cfg(unix)] - /// # use std::os::unix::io::{AsFd, BorrowedFd}; + /// # #[cfg(any(unix, target_os = "wasi"))] + /// # use std::os::fd::{AsFd, BorrowedFd}; /// /// let mut f = File::open("foo.txt")?; /// # #[cfg(any(unix, target_os = "wasi"))] diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs index 1b3d110426feb..f92a05066706d 100644 --- a/library/std/src/os/fd/raw.rs +++ b/library/std/src/os/fd/raw.rs @@ -42,10 +42,8 @@ pub trait AsRawFd { /// ```no_run /// use std::fs::File; /// # use std::io; - /// #[cfg(unix)] - /// use std::os::unix::io::{AsRawFd, RawFd}; - /// #[cfg(target_os = "wasi")] - /// use std::os::wasi::io::{AsRawFd, RawFd}; + /// #[cfg(any(unix, target_os = "wasi"))] + /// use std::os::fd::{AsRawFd, RawFd}; /// /// let mut f = File::open("foo.txt")?; /// // Note that `raw_fd` is only valid as long as `f` exists. @@ -83,10 +81,8 @@ pub trait FromRawFd { /// ```no_run /// use std::fs::File; /// # use std::io; - /// #[cfg(unix)] - /// use std::os::unix::io::{FromRawFd, IntoRawFd, RawFd}; - /// #[cfg(target_os = "wasi")] - /// use std::os::wasi::io::{FromRawFd, IntoRawFd, RawFd}; + /// #[cfg(any(unix, target_os = "wasi"))] + /// use std::os::fd::{FromRawFd, IntoRawFd, RawFd}; /// /// let f = File::open("foo.txt")?; /// # #[cfg(any(unix, target_os = "wasi"))] @@ -121,10 +117,8 @@ pub trait IntoRawFd { /// ```no_run /// use std::fs::File; /// # use std::io; - /// #[cfg(unix)] - /// use std::os::unix::io::{IntoRawFd, RawFd}; - /// #[cfg(target_os = "wasi")] - /// use std::os::wasi::io::{IntoRawFd, RawFd}; + /// #[cfg(any(unix, target_os = "wasi"))] + /// use std::os::fd::{IntoRawFd, RawFd}; /// /// let f = File::open("foo.txt")?; /// #[cfg(any(unix, target_os = "wasi"))] diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 18c64b5100764..f62f5af774f0e 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -147,7 +147,7 @@ pub mod solid; pub mod vxworks; #[cfg(any(unix, target_os = "wasi", doc))] -mod fd; +pub mod fd; #[cfg(any(target_os = "linux", target_os = "android", doc))] mod net; diff --git a/library/std/src/os/unix/io/fd.rs b/library/std/src/os/unix/io/fd.rs deleted file mode 100644 index d4cb696459b7e..0000000000000 --- a/library/std/src/os/unix/io/fd.rs +++ /dev/null @@ -1,8 +0,0 @@ -//! Owned and borrowed file descriptors. - -// Tests for this module -#[cfg(test)] -mod tests; - -#[stable(feature = "io_safety", since = "1.63.0")] -pub use crate::os::fd::owned::*; diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs index 3ab5606f8897d..25b5dbff14f30 100644 --- a/library/std/src/os/unix/io/mod.rs +++ b/library/std/src/os/unix/io/mod.rs @@ -77,10 +77,9 @@ #![stable(feature = "rust1", since = "1.0.0")] -mod fd; -mod raw; - -#[stable(feature = "io_safety", since = "1.63.0")] -pub use fd::*; #[stable(feature = "rust1", since = "1.0.0")] -pub use raw::*; +pub use crate::os::fd::*; + +// Tests for this module +#[cfg(test)] +mod tests; diff --git a/library/std/src/os/unix/io/raw.rs b/library/std/src/os/unix/io/raw.rs deleted file mode 100644 index a4d2ba797d9c4..0000000000000 --- a/library/std/src/os/unix/io/raw.rs +++ /dev/null @@ -1,6 +0,0 @@ -//! Unix-specific extensions to general I/O primitives. - -#![stable(feature = "rust1", since = "1.0.0")] - -#[stable(feature = "rust1", since = "1.0.0")] -pub use crate::os::fd::raw::*; diff --git a/library/std/src/os/unix/io/fd/tests.rs b/library/std/src/os/unix/io/tests.rs similarity index 100% rename from library/std/src/os/unix/io/fd/tests.rs rename to library/std/src/os/unix/io/tests.rs diff --git a/library/std/src/os/wasi/io/mod.rs b/library/std/src/os/wasi/io/mod.rs index 6c884e2eaf471..d528590d75b9a 100644 --- a/library/std/src/os/wasi/io/mod.rs +++ b/library/std/src/os/wasi/io/mod.rs @@ -1,12 +1,6 @@ //! WASI-specific extensions to general I/O primitives. -#![deny(unsafe_op_in_unsafe_fn)] #![unstable(feature = "wasi_ext", issue = "71213")] -mod fd; -mod raw; - -#[unstable(feature = "wasi_ext", issue = "71213")] -pub use fd::*; #[unstable(feature = "wasi_ext", issue = "71213")] -pub use raw::*; +pub use crate::os::fd::*; diff --git a/src/test/rustdoc-js-std/asrawfd.js b/src/test/rustdoc-js-std/asrawfd.js index fd228a59099e9..369a34f9c6eb7 100644 --- a/src/test/rustdoc-js-std/asrawfd.js +++ b/src/test/rustdoc-js-std/asrawfd.js @@ -6,9 +6,9 @@ const EXPECTED = { 'others': [ // Reproduction test for https://github.com/rust-lang/rust/issues/78724 // Validate that type alias methods get the correct path. - { 'path': 'std::os::unix::io::AsRawFd', 'name': 'as_raw_fd' }, - { 'path': 'std::os::wasi::io::AsRawFd', 'name': 'as_raw_fd' }, + { 'path': 'std::os::fd::AsRawFd', 'name': 'as_raw_fd' }, + { 'path': 'std::os::fd::AsRawFd', 'name': 'as_raw_fd' }, { 'path': 'std::os::linux::process::PidFd', 'name': 'as_raw_fd' }, - { 'path': 'std::os::unix::io::RawFd', 'name': 'as_raw_fd' }, + { 'path': 'std::os::fd::RawFd', 'name': 'as_raw_fd' }, ], }; diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.rs b/src/test/ui-fulldeps/internal-lints/diagnostics.rs index 18e39108ecab1..9a5100ce17f53 100644 --- a/src/test/ui-fulldeps/internal-lints/diagnostics.rs +++ b/src/test/ui-fulldeps/internal-lints/diagnostics.rs @@ -19,14 +19,14 @@ use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; #[derive(Diagnostic)] -#[diag(parser::expect_path)] +#[diag(compiletest::example)] struct DeriveDiagnostic { #[primary_span] span: Span, } #[derive(Subdiagnostic)] -#[note(parser::add_paren)] +#[note(compiletest::example)] struct Note { #[primary_span] span: Span, @@ -45,7 +45,7 @@ pub struct TranslatableInIntoDiagnostic; impl<'a> IntoDiagnostic<'a, ErrorGuaranteed> for TranslatableInIntoDiagnostic { fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - handler.struct_err(fluent::parser::expect_path) + handler.struct_err(fluent::compiletest::example) } } @@ -62,12 +62,12 @@ pub struct TranslatableInAddToDiagnostic; impl AddToDiagnostic for TranslatableInAddToDiagnostic { fn add_to_diagnostic(self, diag: &mut Diagnostic) { - diag.note(fluent::typeck::note); + diag.note(fluent::compiletest::note); } } pub fn make_diagnostics<'a>(handler: &'a Handler) { - let _diag = handler.struct_err(fluent::parser::expect_path); + let _diag = handler.struct_err(fluent::compiletest::example); //~^ ERROR diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls let _diag = handler.struct_err("untranslatable diagnostic"); diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.stderr b/src/test/ui-fulldeps/internal-lints/diagnostics.stderr index 9219d09e9b401..f5f92ac1e7fbe 100644 --- a/src/test/ui-fulldeps/internal-lints/diagnostics.stderr +++ b/src/test/ui-fulldeps/internal-lints/diagnostics.stderr @@ -19,7 +19,7 @@ LL | diag.note("untranslatable diagnostic"); error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls --> $DIR/diagnostics.rs:70:25 | -LL | let _diag = handler.struct_err(fluent::parser::expect_path); +LL | let _diag = handler.struct_err(fluent::compiletest::example); | ^^^^^^^^^^ | note: the lint level is defined here diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 3d363cae47310..e3ea5507eba14 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(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct Hello {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct HelloWarn {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] //~^ ERROR unsupported type attribute for diagnostic derive enum enum DiagnosticOnEnum { Foo, @@ -46,13 +46,13 @@ enum DiagnosticOnEnum { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] #[diag = "E0123"] //~^ ERROR `#[diag = ...]` is not a valid attribute struct WrongStructAttrStyle {} #[derive(Diagnostic)] -#[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[nonsense(compiletest::example, code = "E0123")] //~^ ERROR `#[nonsense(...)]` is not a valid attribute //~^^ ERROR diagnostic slug not specified //~^^^ ERROR cannot find attribute `nonsense` in this scope @@ -90,12 +90,12 @@ struct InvalidNestedStructAttr2 {} struct InvalidNestedStructAttr3 {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")] +#[diag(compiletest::example, code = "E0123", slug = "foo")] //~^ ERROR `#[diag(slug = ...)]` is not a valid attribute struct InvalidNestedStructAttr4 {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct WrongPlaceField { #[suggestion = "bar"] //~^ ERROR `#[suggestion = ...]` is not a valid attribute @@ -103,20 +103,20 @@ struct WrongPlaceField { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0456")] +#[diag(compiletest::example, code = "E0123")] +#[diag(compiletest::example, code = "E0456")] //~^ ERROR specified multiple times //~^^ ERROR specified multiple times struct DiagSpecifiedTwice {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] +#[diag(compiletest::example, code = "E0456", code = "E0457")] //~^ ERROR specified multiple times struct CodeSpecifiedTwice {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")] -//~^ ERROR `#[diag(typeck::ambiguous_lifetime_bound)]` is not a valid attribute +#[diag(compiletest::example, compiletest::example, code = "E0456")] +//~^ ERROR `#[diag(compiletest::example)]` is not a valid attribute struct SlugSpecifiedTwice {} #[derive(Diagnostic)] @@ -128,11 +128,11 @@ struct KindNotProvided {} //~ ERROR diagnostic slug not specified struct SlugNotProvided {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound)] +#[diag(compiletest::example)] struct CodeNotProvided {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct MessageWrongType { #[primary_span] //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` @@ -140,7 +140,7 @@ struct MessageWrongType { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct InvalidPathFieldAttr { #[nonsense] //~^ ERROR `#[nonsense]` is not a valid attribute @@ -149,34 +149,34 @@ struct InvalidPathFieldAttr { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithField { name: String, - #[label(typeck::label)] + #[label(compiletest::label)] span: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithMessageAppliedToField { - #[label(typeck::label)] + #[label(compiletest::label)] //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` name: String, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithNonexistentField { - #[suggestion(typeck::suggestion, code = "{name}")] + #[suggestion(compiletest::suggestion, code = "{name}")] //~^ ERROR `name` doesn't refer to a field on this type suggestion: (Span, Applicability), } #[derive(Diagnostic)] //~^ ERROR invalid format string: expected `'}'` -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorMissingClosingBrace { - #[suggestion(typeck::suggestion, code = "{name")] + #[suggestion(compiletest::suggestion, code = "{name")] suggestion: (Span, Applicability), name: String, val: usize, @@ -184,49 +184,49 @@ struct ErrorMissingClosingBrace { #[derive(Diagnostic)] //~^ ERROR invalid format string: unmatched `}` -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorMissingOpeningBrace { - #[suggestion(typeck::suggestion, code = "name}")] + #[suggestion(compiletest::suggestion, code = "name}")] suggestion: (Span, Applicability), name: String, val: usize, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct LabelOnSpan { - #[label(typeck::label)] + #[label(compiletest::label)] sp: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct LabelOnNonSpan { - #[label(typeck::label)] + #[label(compiletest::label)] //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` id: u32, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct Suggest { - #[suggestion(typeck::suggestion, code = "This is the suggested code")] - #[suggestion_short(typeck::suggestion, code = "This is the suggested code")] - #[suggestion_hidden(typeck::suggestion, code = "This is the suggested code")] - #[suggestion_verbose(typeck::suggestion, code = "This is the suggested code")] + #[suggestion(compiletest::suggestion, code = "This is the suggested code")] + #[suggestion_short(compiletest::suggestion, code = "This is the suggested code")] + #[suggestion_hidden(compiletest::suggestion, code = "This is the suggested code")] + #[suggestion_verbose(compiletest::suggestion, code = "This is the suggested code")] suggestion: (Span, Applicability), } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithoutCode { - #[suggestion(typeck::suggestion)] + #[suggestion(compiletest::suggestion)] //~^ ERROR suggestion without `code = "..."` suggestion: (Span, Applicability), } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithBadKey { #[suggestion(nonsense = "bar")] //~^ ERROR `#[suggestion(nonsense = ...)]` is not a valid attribute @@ -235,7 +235,7 @@ struct SuggestWithBadKey { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithShorthandMsg { #[suggestion(msg = "bar")] //~^ ERROR `#[suggestion(msg = ...)]` is not a valid attribute @@ -244,52 +244,52 @@ struct SuggestWithShorthandMsg { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithoutMsg { #[suggestion(code = "bar")] suggestion: (Span, Applicability), } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithTypesSwapped { - #[suggestion(typeck::suggestion, code = "This is suggested code")] + #[suggestion(compiletest::suggestion, code = "This is suggested code")] suggestion: (Applicability, Span), } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithWrongTypeApplicabilityOnly { - #[suggestion(typeck::suggestion, code = "This is suggested code")] + #[suggestion(compiletest::suggestion, code = "This is suggested code")] //~^ ERROR wrong field type for suggestion suggestion: Applicability, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithSpanOnly { - #[suggestion(typeck::suggestion, code = "This is suggested code")] + #[suggestion(compiletest::suggestion, code = "This is suggested code")] suggestion: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithDuplicateSpanAndApplicability { - #[suggestion(typeck::suggestion, code = "This is suggested code")] + #[suggestion(compiletest::suggestion, code = "This is suggested code")] suggestion: (Span, Span, Applicability), //~^ ERROR specified multiple times } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithDuplicateApplicabilityAndSpan { - #[suggestion(typeck::suggestion, code = "This is suggested code")] + #[suggestion(compiletest::suggestion, code = "This is suggested code")] suggestion: (Applicability, Applicability, Span), //~^ ERROR specified multiple times } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct WrongKindOfAnnotation { #[label = "bar"] //~^ ERROR `#[label = ...]` is not a valid attribute @@ -297,38 +297,38 @@ struct WrongKindOfAnnotation { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct OptionsInErrors { - #[label(typeck::label)] + #[label(compiletest::label)] label: Option, - #[suggestion(typeck::suggestion, code = "...")] + #[suggestion(compiletest::suggestion, code = "...")] opt_sugg: Option<(Span, Applicability)>, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0456")] +#[diag(compiletest::example, code = "E0456")] struct MoveOutOfBorrowError<'tcx> { name: Ident, ty: Ty<'tcx>, #[primary_span] - #[label(typeck::label)] + #[label(compiletest::label)] span: Span, - #[label(typeck::label)] + #[label(compiletest::label)] other_span: Span, - #[suggestion(typeck::suggestion, code = "{name}.clone()")] + #[suggestion(compiletest::suggestion, code = "{name}.clone()")] opt_sugg: Option<(Span, Applicability)>, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithLifetime<'a> { - #[label(typeck::label)] + #[label(compiletest::label)] span: Span, name: &'a str, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithDefaultLabelAttr<'a> { #[label] span: Span, @@ -337,7 +337,7 @@ struct ErrorWithDefaultLabelAttr<'a> { #[derive(Diagnostic)] //~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ArgFieldWithoutSkip { #[primary_span] span: Span, @@ -345,7 +345,7 @@ struct ArgFieldWithoutSkip { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ArgFieldWithSkip { #[primary_span] span: Span, @@ -356,116 +356,116 @@ struct ArgFieldWithSkip { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithSpannedNote { #[note] span: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithSpannedNoteCustom { - #[note(typeck::note)] + #[note(compiletest::note)] span: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] #[note] struct ErrorWithNote { val: String, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] -#[note(typeck::note)] +#[diag(compiletest::example, code = "E0123")] +#[note(compiletest::note)] struct ErrorWithNoteCustom { val: String, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithSpannedHelp { #[help] span: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithSpannedHelpCustom { - #[help(typeck::help)] + #[help(compiletest::help)] span: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] #[help] struct ErrorWithHelp { val: String, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] -#[help(typeck::help)] +#[diag(compiletest::example, code = "E0123")] +#[help(compiletest::help)] struct ErrorWithHelpCustom { val: String, } #[derive(Diagnostic)] #[help] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithHelpWrongOrder { val: String, } #[derive(Diagnostic)] -#[help(typeck::help)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[help(compiletest::help)] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithHelpCustomWrongOrder { val: String, } #[derive(Diagnostic)] #[note] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithNoteWrongOrder { val: String, } #[derive(Diagnostic)] -#[note(typeck::note)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[note(compiletest::note)] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithNoteCustomWrongOrder { val: String, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ApplicabilityInBoth { - #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] + #[suggestion(compiletest::suggestion, code = "...", applicability = "maybe-incorrect")] //~^ ERROR specified multiple times suggestion: (Span, Applicability), } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct InvalidApplicability { - #[suggestion(typeck::suggestion, code = "...", applicability = "batman")] + #[suggestion(compiletest::suggestion, code = "...", applicability = "batman")] //~^ ERROR invalid applicability suggestion: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ValidApplicability { - #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] + #[suggestion(compiletest::suggestion, code = "...", applicability = "maybe-incorrect")] suggestion: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct NoApplicability { - #[suggestion(typeck::suggestion, code = "...")] + #[suggestion(compiletest::suggestion, code = "...")] suggestion: Span, } @@ -474,14 +474,14 @@ struct NoApplicability { struct Note; #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound)] +#[diag(compiletest::example)] struct Subdiagnostic { #[subdiagnostic] note: Note, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct VecField { #[primary_span] #[label] @@ -489,58 +489,58 @@ struct VecField { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct UnitField { #[primary_span] spans: Span, #[help] foo: (), - #[help(typeck::help)] + #[help(compiletest::help)] bar: (), } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct OptUnitField { #[primary_span] spans: Span, #[help] foo: Option<()>, - #[help(typeck::help)] + #[help(compiletest::help)] bar: Option<()>, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct LabelWithTrailingPath { - #[label(typeck::label, foo)] + #[label(compiletest::label, foo)] //~^ ERROR `#[label(foo)]` is not a valid attribute span: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct LabelWithTrailingNameValue { - #[label(typeck::label, foo = "...")] + #[label(compiletest::label, foo = "...")] //~^ ERROR `#[label(foo = ...)]` is not a valid attribute span: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct LabelWithTrailingList { - #[label(typeck::label, foo("..."))] + #[label(compiletest::label, foo("..."))] //~^ ERROR `#[label(foo(...))]` is not a valid attribute span: Span, } #[derive(LintDiagnostic)] -#[diag(typeck::ambiguous_lifetime_bound)] +#[diag(compiletest::example)] struct LintsGood { } #[derive(LintDiagnostic)] -#[diag(typeck::ambiguous_lifetime_bound)] +#[diag(compiletest::example)] struct PrimarySpanOnLint { #[primary_span] //~^ ERROR `#[primary_span]` is not a valid attribute @@ -548,97 +548,97 @@ struct PrimarySpanOnLint { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithMultiSpan { #[primary_span] span: MultiSpan, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] #[warning] struct ErrorWithWarn { val: String, } #[derive(Diagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[error(compiletest::example, 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(Diagnostic)] -#[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[warn_(compiletest::example, code = "E0123")] //~^ ERROR `#[warn_(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified //~| ERROR cannot find attribute `warn_` in this scope struct WarnAttribute {} #[derive(Diagnostic)] -#[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[lint(compiletest::example, 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")] +#[lint(compiletest::example, code = "E0123")] //~^ ERROR `#[lint(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified //~| ERROR cannot find attribute `lint` in this scope struct LintAttributeOnLintDiag {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct DuplicatedSuggestionCode { - #[suggestion(typeck::suggestion, code = "...", code = ",,,")] + #[suggestion(compiletest::suggestion, code = "...", code = ",,,")] //~^ ERROR specified multiple times suggestion: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct InvalidTypeInSuggestionTuple { - #[suggestion(typeck::suggestion, code = "...")] + #[suggestion(compiletest::suggestion, code = "...")] suggestion: (Span, usize), //~^ ERROR wrong types for suggestion } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct MissingApplicabilityInSuggestionTuple { - #[suggestion(typeck::suggestion, code = "...")] + #[suggestion(compiletest::suggestion, code = "...")] suggestion: (Span,), //~^ ERROR wrong types for suggestion } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct MissingCodeInSuggestion { - #[suggestion(typeck::suggestion)] + #[suggestion(compiletest::suggestion)] //~^ ERROR suggestion without `code = "..."` suggestion: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] -#[multipart_suggestion(typeck::suggestion)] +#[diag(compiletest::example, code = "E0123")] +#[multipart_suggestion(compiletest::suggestion)] //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute //~| ERROR cannot find attribute `multipart_suggestion` in this scope #[multipart_suggestion()] //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute //~| ERROR cannot find attribute `multipart_suggestion` in this scope struct MultipartSuggestion { - #[multipart_suggestion(typeck::suggestion)] + #[multipart_suggestion(compiletest::suggestion)] //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute //~| ERROR cannot find attribute `multipart_suggestion` in this scope suggestion: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] -#[suggestion(typeck::suggestion, code = "...")] +#[diag(compiletest::example, code = "E0123")] +#[suggestion(compiletest::suggestion, code = "...")] //~^ ERROR `#[suggestion(...)]` is not a valid attribute struct SuggestionOnStruct { #[primary_span] @@ -646,7 +646,7 @@ struct SuggestionOnStruct { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] #[label] //~^ ERROR `#[label]` is not a valid attribute struct LabelOnStruct { @@ -656,19 +656,19 @@ struct LabelOnStruct { #[derive(Diagnostic)] enum ExampleEnum { - #[diag(typeck::ambiguous_lifetime_bound)] + #[diag(compiletest::example)] Foo { #[primary_span] sp: Span, #[note] note_sp: Span, }, - #[diag(typeck::ambiguous_lifetime_bound)] + #[diag(compiletest::example)] Bar { #[primary_span] sp: Span, }, - #[diag(typeck::ambiguous_lifetime_bound)] + #[diag(compiletest::example)] Baz, } diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 21a402c7b9da8..29452bf7c60b2 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -1,8 +1,8 @@ error: unsupported type attribute for diagnostic derive enum --> $DIR/diagnostic-derive.rs:39:1 | -LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[diag(compiletest::example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:42:5 @@ -10,7 +10,7 @@ error: diagnostic slug not specified LL | Foo, | ^^^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:44:5 @@ -18,7 +18,7 @@ error: diagnostic slug not specified LL | Bar, | ^^^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[diag = ...]` is not a valid attribute --> $DIR/diagnostic-derive.rs:50:1 @@ -29,20 +29,20 @@ LL | #[diag = "E0123"] error: `#[nonsense(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:55:1 | -LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[nonsense(compiletest::example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:55:1 | -LL | / #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | / #[nonsense(compiletest::example, code = "E0123")] LL | | LL | | LL | | LL | | struct InvalidStructAttr {} | |___________________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[diag("...")]` is not a valid attribute --> $DIR/diagnostic-derive.rs:62:8 @@ -61,7 +61,7 @@ LL | | LL | | struct InvalidLitNestedAttr {} | |______________________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[diag(nonsense(...))]` is not a valid attribute --> $DIR/diagnostic-derive.rs:73:8 @@ -80,7 +80,7 @@ LL | | LL | | struct InvalidNestedStructAttr1 {} | |__________________________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[diag(nonsense = ...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:79:8 @@ -108,7 +108,7 @@ LL | | LL | | struct InvalidNestedStructAttr2 {} | |__________________________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[diag(nonsense = ...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:86:8 @@ -134,13 +134,13 @@ LL | | LL | | struct InvalidNestedStructAttr3 {} | |__________________________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[diag(slug = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:93:58 + --> $DIR/diagnostic-derive.rs:93:46 | -LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")] - | ^^^^^^^^^^^^ +LL | #[diag(compiletest::example, code = "E0123", slug = "foo")] + | ^^^^^^^^^^^^ | = help: only `code` is a valid nested attributes following the slug @@ -153,44 +153,44 @@ LL | #[suggestion = "bar"] error: specified multiple times --> $DIR/diagnostic-derive.rs:107:8 | -LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[diag(compiletest::example, code = "E0456")] + | ^^^^^^^^^^^^^^^^^^^^ | note: previously specified here --> $DIR/diagnostic-derive.rs:106:8 | -LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[diag(compiletest::example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:107:49 + --> $DIR/diagnostic-derive.rs:107:37 | -LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456")] - | ^^^^^^^ +LL | #[diag(compiletest::example, code = "E0456")] + | ^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:106:49 + --> $DIR/diagnostic-derive.rs:106:37 | -LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^ +LL | #[diag(compiletest::example, code = "E0123")] + | ^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:113:65 + --> $DIR/diagnostic-derive.rs:113:53 | -LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] - | ^^^^^^^ +LL | #[diag(compiletest::example, code = "E0456", code = "E0457")] + | ^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:113:49 + --> $DIR/diagnostic-derive.rs:113:37 | -LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] - | ^^^^^^^ +LL | #[diag(compiletest::example, code = "E0456", code = "E0457")] + | ^^^^^^^ -error: `#[diag(typeck::ambiguous_lifetime_bound)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:118:42 +error: `#[diag(compiletest::example)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:118:30 | -LL | #[diag(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[diag(compiletest::example, compiletest::example, code = "E0456")] + | ^^^^^^^^^^^^^^^^^^^^ | = help: diagnostic slug must be the first argument @@ -200,7 +200,7 @@ error: diagnostic slug not specified LL | struct KindNotProvided {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:126:1 @@ -210,7 +210,7 @@ LL | | LL | | struct SlugNotProvided {} | |_________________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` --> $DIR/diagnostic-derive.rs:137:5 @@ -227,14 +227,14 @@ LL | #[nonsense] error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` --> $DIR/diagnostic-derive.rs:162:5 | -LL | #[label(typeck::label)] - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[label(compiletest::label)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `name` doesn't refer to a field on this type - --> $DIR/diagnostic-derive.rs:170:45 + --> $DIR/diagnostic-derive.rs:170:50 | -LL | #[suggestion(typeck::suggestion, code = "{name}")] - | ^^^^^^^^ +LL | #[suggestion(compiletest::suggestion, code = "{name}")] + | ^^^^^^^^ error: invalid format string: expected `'}'` but string was terminated --> $DIR/diagnostic-derive.rs:175:10 @@ -257,14 +257,14 @@ LL | #[derive(Diagnostic)] error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` --> $DIR/diagnostic-derive.rs:205:5 | -LL | #[label(typeck::label)] - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[label(compiletest::label)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: suggestion without `code = "..."` --> $DIR/diagnostic-derive.rs:223:5 | -LL | #[suggestion(typeck::suggestion)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(compiletest::suggestion)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[suggestion(nonsense = ...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:231:18 @@ -297,7 +297,7 @@ LL | #[suggestion(msg = "bar")] error: wrong field type for suggestion --> $DIR/diagnostic-derive.rs:263:5 | -LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")] +LL | / #[suggestion(compiletest::suggestion, code = "This is suggested code")] LL | | LL | | suggestion: Applicability, | |_____________________________^ @@ -335,10 +335,10 @@ LL | #[label = "bar"] | ^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:445:52 + --> $DIR/diagnostic-derive.rs:445:57 | -LL | #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(compiletest::suggestion, code = "...", applicability = "maybe-incorrect")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here --> $DIR/diagnostic-derive.rs:447:24 @@ -347,30 +347,30 @@ LL | suggestion: (Span, Applicability), | ^^^^^^^^^^^^^ error: invalid applicability - --> $DIR/diagnostic-derive.rs:453:52 + --> $DIR/diagnostic-derive.rs:453:57 | -LL | #[suggestion(typeck::suggestion, code = "...", applicability = "batman")] - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(compiletest::suggestion, code = "...", applicability = "batman")] + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[label(foo)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:516:28 + --> $DIR/diagnostic-derive.rs:516:33 | -LL | #[label(typeck::label, foo)] - | ^^^ +LL | #[label(compiletest::label, foo)] + | ^^^ | = help: a diagnostic slug must be the first argument to the attribute error: `#[label(foo = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:524:28 + --> $DIR/diagnostic-derive.rs:524:33 | -LL | #[label(typeck::label, foo = "...")] - | ^^^^^^^^^^^ +LL | #[label(compiletest::label, foo = "...")] + | ^^^^^^^^^^^ error: `#[label(foo(...))]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:532:28 + --> $DIR/diagnostic-derive.rs:532:33 | -LL | #[label(typeck::label, foo("..."))] - | ^^^^^^^^^^ +LL | #[label(compiletest::label, foo("..."))] + | ^^^^^^^^^^ error: `#[primary_span]` is not a valid attribute --> $DIR/diagnostic-derive.rs:545:5 @@ -383,86 +383,86 @@ LL | #[primary_span] error: `#[error(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:565:1 | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[error(compiletest::example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:565:1 | -LL | / #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | / #[error(compiletest::example, code = "E0123")] LL | | LL | | LL | | LL | | struct ErrorAttribute {} | |________________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[warn_(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:572:1 | -LL | #[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[warn_(compiletest::example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:572:1 | -LL | / #[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | / #[warn_(compiletest::example, code = "E0123")] LL | | LL | | LL | | LL | | struct WarnAttribute {} | |_______________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[lint(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:579:1 | -LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[lint(compiletest::example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:579:1 | -LL | / #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | / #[lint(compiletest::example, 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)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[lint(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:586:1 | -LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[lint(compiletest::example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:586:1 | -LL | / #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | / #[lint(compiletest::example, code = "E0123")] LL | | LL | | LL | | LL | | struct LintAttributeOnLintDiag {} | |_________________________________^ | - = help: specify the slug as the first argument to the attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the attribute, such as `#[diag(hir_analysis::example_error)]` error: specified multiple times - --> $DIR/diagnostic-derive.rs:595:52 + --> $DIR/diagnostic-derive.rs:595:57 | -LL | #[suggestion(typeck::suggestion, code = "...", code = ",,,")] - | ^^^^^^^^^^^^ +LL | #[suggestion(compiletest::suggestion, code = "...", code = ",,,")] + | ^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:595:38 + --> $DIR/diagnostic-derive.rs:595:43 | -LL | #[suggestion(typeck::suggestion, code = "...", code = ",,,")] - | ^^^^^^^^^^^^ +LL | #[suggestion(compiletest::suggestion, code = "...", code = ",,,")] + | ^^^^^^^^^^^^ error: wrong types for suggestion --> $DIR/diagnostic-derive.rs:604:24 @@ -483,14 +483,14 @@ LL | suggestion: (Span,), error: suggestion without `code = "..."` --> $DIR/diagnostic-derive.rs:619:5 | -LL | #[suggestion(typeck::suggestion)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(compiletest::suggestion)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[multipart_suggestion(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:626:1 | -LL | #[multipart_suggestion(typeck::suggestion)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[multipart_suggestion(compiletest::suggestion)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider creating a `Subdiagnostic` instead @@ -505,16 +505,16 @@ LL | #[multipart_suggestion()] error: `#[multipart_suggestion(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:633:5 | -LL | #[multipart_suggestion(typeck::suggestion)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[multipart_suggestion(compiletest::suggestion)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider creating a `Subdiagnostic` instead error: `#[suggestion(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:641:1 | -LL | #[suggestion(typeck::suggestion, code = "...")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(compiletest::suggestion, code = "...")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: `#[label]` and `#[suggestion]` can only be applied to fields @@ -529,7 +529,7 @@ LL | #[label] error: cannot find attribute `nonsense` in this scope --> $DIR/diagnostic-derive.rs:55:3 | -LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | #[nonsense(compiletest::example, code = "E0123")] | ^^^^^^^^ error: cannot find attribute `nonsense` in this scope @@ -541,31 +541,31 @@ LL | #[nonsense] error: cannot find attribute `error` in this scope --> $DIR/diagnostic-derive.rs:565:3 | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | #[error(compiletest::example, code = "E0123")] | ^^^^^ error: cannot find attribute `warn_` in this scope --> $DIR/diagnostic-derive.rs:572:3 | -LL | #[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | #[warn_(compiletest::example, code = "E0123")] | ^^^^^ help: a built-in attribute with a similar name exists: `warn` error: cannot find attribute `lint` in this scope --> $DIR/diagnostic-derive.rs:579:3 | -LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | #[lint(compiletest::example, 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:586:3 | -LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | #[lint(compiletest::example, code = "E0123")] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `multipart_suggestion` in this scope --> $DIR/diagnostic-derive.rs:626:3 | -LL | #[multipart_suggestion(typeck::suggestion)] +LL | #[multipart_suggestion(compiletest::suggestion)] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope @@ -577,7 +577,7 @@ LL | #[multipart_suggestion()] error: cannot find attribute `multipart_suggestion` in this scope --> $DIR/diagnostic-derive.rs:633:7 | -LL | #[multipart_suggestion(typeck::suggestion)] +LL | #[multipart_suggestion(compiletest::suggestion)] | ^^^^^^^^^^^^^^^^^^^^ error[E0425]: cannot find value `nonsense` in module `rustc_errors::fluent` diff --git a/src/test/ui/generic-associated-types/issue-102333.rs b/src/test/ui/generic-associated-types/issue-102333.rs new file mode 100644 index 0000000000000..6c72563322f55 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-102333.rs @@ -0,0 +1,15 @@ +// check-pass + +trait A { + type T: B = ()>; +} + +trait B { + type U; +} + +fn f() { + let _: <::T as B>::U<1i32> = (); +} + +fn main() {} diff --git a/src/test/ui/generics/issue-94923.rs b/src/test/ui/generics/issue-94923.rs new file mode 100644 index 0000000000000..d337a5dffc934 --- /dev/null +++ b/src/test/ui/generics/issue-94923.rs @@ -0,0 +1,49 @@ +// run-pass +// regression test for issue #94923 +// min-llvm-version: 15.0.0 +// compile-flags: -C opt-level=3 + +fn f0(mut x: usize) -> usize { + for _ in 0..1000 { + x *= 123; + x %= 99 + } + x + 321 // function composition is not just longer iteration +} + +fn f1(x: usize) -> usize { + f0::<(i8, T)>(f0::<(u8, T)>(x)) +} + +fn f2(x: usize) -> usize { + f1::<(i8, T)>(f1::<(u8, T)>(x)) +} + +fn f3(x: usize) -> usize { + f2::<(i8, T)>(f2::<(u8, T)>(x)) +} + +fn f4(x: usize) -> usize { + f3::<(i8, T)>(f3::<(u8, T)>(x)) +} + +fn f5(x: usize) -> usize { + f4::<(i8, T)>(f4::<(u8, T)>(x)) +} + +fn f6(x: usize) -> usize { + f5::<(i8, T)>(f5::<(u8, T)>(x)) +} + +fn f7(x: usize) -> usize { + f6::<(i8, T)>(f6::<(u8, T)>(x)) +} + +fn f8(x: usize) -> usize { + f7::<(i8, T)>(f7::<(u8, T)>(x)) +} + +fn main() { + let y = f8::<()>(1); + assert_eq!(y, 348); +}