From d031795c818c6d1ac1c27a594cd9b227f0c53229 Mon Sep 17 00:00:00 2001 From: Daniel Huang Date: Thu, 14 Dec 2023 19:05:03 -0500 Subject: [PATCH 01/12] Update c_str.rs --- library/core/src/ffi/c_str.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index e7ec1fb73cdb5..bb839a71e90e6 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -205,7 +205,7 @@ impl CStr { /// * The memory pointed to by `ptr` must contain a valid nul terminator at the /// end of the string. /// - /// * `ptr` must be [valid] for reads of bytes up to and including the null terminator. + /// * `ptr` must be [valid] for reads of bytes up to and including the nul terminator. /// This means in particular: /// /// * The entire memory range of this `CStr` must be contained within a single allocated object! @@ -415,7 +415,7 @@ impl CStr { let mut i = bytes.len().saturating_sub(1); assert!(!bytes.is_empty() && bytes[i] == 0, "input was not nul-terminated"); - // Ending null byte exists, skip to the rest. + // Ending nul byte exists, skip to the rest. while i != 0 { i -= 1; let byte = bytes[i]; From f2f9b1d82a123667b63d5fa6b5ccc9c59d290320 Mon Sep 17 00:00:00 2001 From: Daniel Huang Date: Thu, 14 Dec 2023 19:08:36 -0500 Subject: [PATCH 02/12] Update c_str.rs --- library/alloc/src/ffi/c_str.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index 62856fc9a49b5..4a4a3abd47f39 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -421,7 +421,7 @@ impl CString { /// Failure to call [`CString::from_raw`] will lead to a memory leak. /// /// The C side must **not** modify the length of the string (by writing a - /// `null` somewhere inside the string or removing the final one) before + /// nul byte somewhere inside the string or removing the final one) before /// it makes it back into Rust using [`CString::from_raw`]. See the safety section /// in [`CString::from_raw`]. /// @@ -797,7 +797,7 @@ impl From> for CString { #[stable(feature = "cstring_from_vec_of_nonzerou8", since = "1.43.0")] impl From> for CString { /// Converts a [Vec]<[NonZeroU8]> into a [`CString`] without - /// copying nor checking for inner null bytes. + /// copying nor checking for inner nul bytes. #[inline] fn from(v: Vec) -> CString { unsafe { @@ -809,7 +809,7 @@ impl From> for CString { let (ptr, len, cap): (*mut NonZeroU8, _, _) = Vec::into_raw_parts(v); Vec::from_raw_parts(ptr.cast::(), len, cap) }; - // SAFETY: `v` cannot contain null bytes, given the type-level + // SAFETY: `v` cannot contain nul bytes, given the type-level // invariant of `NonZeroU8`. Self::_from_vec_unchecked(v) } From 8142e8555a1ed10dad997a2c2b71e9ad73ea1bde Mon Sep 17 00:00:00 2001 From: Arthur Carcano Date: Fri, 15 Dec 2023 15:01:49 +0100 Subject: [PATCH 03/12] Remove an unneeded allocation --- .../src/traits/error_reporting/suggestions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 9073cd6ac47a1..1eaee72455ec2 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -4665,7 +4665,7 @@ pub trait NextTypeParamName { impl NextTypeParamName for &[hir::GenericParam<'_>] { fn next_type_param_name(&self, name: Option<&str>) -> String { // This is the list of possible parameter names that we might suggest. - let name = name.and_then(|n| n.chars().next()).map(|c| c.to_string().to_uppercase()); + let name = name.and_then(|n| n.chars().next()).map(|c| c.to_uppercase().to_string()); let name = name.as_deref(); let possible_names = [name.unwrap_or("T"), "T", "U", "V", "X", "Y", "Z", "A", "B", "C"]; let used_names = self From 7f565ed282455b59dea725f25c251bde30540fcb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 8 Dec 2023 01:52:56 +0000 Subject: [PATCH 04/12] Don't pass lint back out of lint decorator --- .../rustc_codegen_ssa/src/codegen_attrs.rs | 4 ++- .../src/astconv/generics.rs | 2 +- .../rustc_hir_analysis/src/astconv/lint.rs | 1 - .../rustc_hir_analysis/src/astconv/mod.rs | 2 -- .../rustc_hir_analysis/src/check/check.rs | 6 ++-- .../src/check/compare_impl_item.rs | 1 - .../src/check/intrinsicck.rs | 1 - .../rustc_hir_analysis/src/check_unused.rs | 2 +- .../src/coherence/orphan.rs | 2 +- .../src/collect/generics_of.rs | 2 +- .../src/collect/resolve_bound_vars.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- .../src/method/prelude2021.rs | 6 ---- compiler/rustc_hir_typeck/src/method/probe.rs | 4 +-- compiler/rustc_hir_typeck/src/pat.rs | 2 -- compiler/rustc_hir_typeck/src/upvar.rs | 2 -- compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_lint/src/context.rs | 30 +++++++------------ compiler/rustc_lint/src/early.rs | 8 +---- compiler/rustc_lint/src/levels.rs | 9 ++---- compiler/rustc_lint/src/non_fmt_panic.rs | 3 +- compiler/rustc_middle/src/lint.rs | 11 ++----- compiler/rustc_middle/src/middle/stability.rs | 3 +- .../rustc_middle/src/mir/interpret/queries.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 14 ++++----- .../src/traits/coherence.rs | 1 - .../src/traits/object_safety.rs | 1 - .../src/traits/specialize/mod.rs | 1 - src/librustdoc/core.rs | 4 ++- src/librustdoc/html/markdown.rs | 10 +++---- .../passes/check_doc_test_visibility.rs | 4 +-- .../passes/collect_intra_doc_links.rs | 2 -- src/librustdoc/passes/lint/bare_urls.rs | 2 +- .../passes/lint/check_code_block_syntax.rs | 2 -- src/librustdoc/passes/lint/html_tags.rs | 4 +-- .../passes/lint/redundant_explicit_links.rs | 4 --- .../passes/lint/unescaped_backticks.rs | 2 -- .../clippy/clippy_utils/src/diagnostics.rs | 6 ---- 38 files changed, 50 insertions(+), 116 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 40a985cf255d5..015ea10d7216c 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -578,7 +578,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { hir_id, no_sanitize_span, "`no_sanitize` will have no effect after inlining", - |lint| lint.span_note(inline_span, "inlining requested here"), + |lint| { + lint.span_note(inline_span, "inlining requested here"); + }, ) } } diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs index 47fbed45b9132..be73c027fdc86 100644 --- a/compiler/rustc_hir_analysis/src/astconv/generics.rs +++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs @@ -661,7 +661,7 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes( args.args[0].hir_id(), multispan, msg, - |lint| lint, + |_| {}, ); } diff --git a/compiler/rustc_hir_analysis/src/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs index 43d4248ab74e2..9afb04b747028 100644 --- a/compiler/rustc_hir_analysis/src/astconv/lint.rs +++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs @@ -122,7 +122,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { Applicability::MachineApplicable, ); self.maybe_lint_blanket_trait_impl(self_ty, lint); - lint }, ); } diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index caae6fa4f065e..0329640a27560 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1506,8 +1506,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident), Applicability::MachineApplicable, ); - - lint }, ); } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index e6245e4d0b146..8413a1cc0dba9 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -51,7 +51,7 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) { hir_id, span, "use of calling convention not supported on this target", - |lint| lint, + |_| {}, ); } } @@ -190,7 +190,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { "static of uninhabited type", |lint| { lint - .note("uninhabited statics cannot be initialized, and any access would be an immediate error") + .note("uninhabited statics cannot be initialized, and any access would be an immediate error"); }, ); } @@ -1093,7 +1093,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) "this {descr} contains `{field_ty}`, which {note}, \ and makes it not a breaking change to become \ non-zero-sized in the future." - )) + )); }, ) } else { diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 00302ec831cef..5a9f3734d17e7 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -574,7 +574,6 @@ fn emit_implied_wf_lint<'tcx>( Applicability::MaybeIncorrect, ); } - lint }, ); } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 2428fe6ae790a..f346427822f54 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -269,7 +269,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { lint.help(format!( "or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}`", )); - lint }, ); } diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs index 9ad73eeffc6ae..36cb8f7a20228 100644 --- a/compiler/rustc_hir_analysis/src/check_unused.rs +++ b/compiler/rustc_hir_analysis/src/check_unused.rs @@ -45,7 +45,7 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) { item.hir_id(), path.span, msg, - |lint| lint, + |_| {}, ); } } diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 451004576292a..88128d22a3db2 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -522,7 +522,7 @@ fn lint_auto_trait_impl<'tcx>( format!( "try using the same sequence of generic parameters as the {self_descr} definition", ), - ) + ); }, ); } diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index c1c2bb62c66e0..3ee2822edd8eb 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -279,7 +279,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { param.hir_id, param.span, TYPE_DEFAULT_NOT_ALLOWED, - |lint| lint, + |_| {}, ); } Defaults::Deny => { diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index a972c51e3eea0..00e920475eced 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -925,7 +925,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { "you can use the `'static` lifetime directly, in place of `{}`", lifetime.ident, ); - lint.help(help) + lint.help(help); }, ); } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 7744f75121eec..3bee42eb89cf9 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -72,7 +72,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { orig_span, custom_note .unwrap_or("any code following this expression is unreachable"), - ) + ); }, ) } diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude2021.rs index 3f1dca5b1deaa..43d258de6ca7a 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude2021.rs @@ -122,8 +122,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("disambiguate the method call with `({self_adjusted})`",), ); } - - lint }, ); } else { @@ -187,8 +185,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ), ); } - - lint }, ); } @@ -307,8 +303,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,), Applicability::MachineApplicable, ); - - lint }, ); } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 4243bce377fb4..bbcc04af6f3ee 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -445,7 +445,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { scope_expr_id, span, "type annotations needed", - |lint| lint, + |_| {}, ); } } else { @@ -1427,8 +1427,6 @@ impl<'tcx> Pick<'tcx> { )); } } - - lint }, ); } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 165fc630787e7..7c00f71da5cd4 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1845,8 +1845,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lint.note(format!( "the pattern is of type `{ty}` and the `non_exhaustive_omitted_patterns` attribute was found", )); - - lint }); } diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 998ee339ae2c4..69d6fb8e2eab7 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -912,8 +912,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::HasPlaceholders ); } - - lint }, ); } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 32eb67ba3a114..045ff38c0568c 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2800,7 +2800,7 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels { NAMED_ASM_LABELS, Some(target_spans), fluent::lint_builtin_asm_labels, - |lint| lint, + |_| {}, BuiltinLintDiagnostics::NamedAsmLabel( "only local labels of the form `:` should be used in inline asm" .to_string(), diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 0911fa70f9725..6def7218fff8e 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -530,9 +530,7 @@ pub trait LintContext { lint: &'static Lint, span: Option>, msg: impl Into, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), diagnostic: BuiltinLintDiagnostics, ) { // We first generate a blank diagnostic. @@ -995,9 +993,7 @@ pub trait LintContext { lint: &'static Lint, span: Option, msg: impl Into, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ); /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`, @@ -1008,7 +1004,9 @@ pub trait LintContext { span: S, decorator: impl for<'a> DecorateLint<'a, ()>, ) { - self.lookup(lint, Some(span), decorator.msg(), |diag| decorator.decorate_lint(diag)); + self.lookup(lint, Some(span), decorator.msg(), |diag| { + decorator.decorate_lint(diag); + }); } /// Emit a lint at the appropriate level, with an associated span. @@ -1022,9 +1020,7 @@ pub trait LintContext { lint: &'static Lint, span: S, msg: impl Into, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { self.lookup(lint, Some(span), msg, decorate); } @@ -1033,7 +1029,7 @@ pub trait LintContext { /// generated by `#[derive(LintDiagnostic)]`). fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> DecorateLint<'a, ()>) { self.lookup(lint, None as Option, decorator.msg(), |diag| { - decorator.decorate_lint(diag) + decorator.decorate_lint(diag); }); } @@ -1047,9 +1043,7 @@ pub trait LintContext { &self, lint: &'static Lint, msg: impl Into, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { self.lookup(lint, None as Option, msg, decorate); } @@ -1113,9 +1107,7 @@ impl<'tcx> LintContext for LateContext<'tcx> { lint: &'static Lint, span: Option, msg: impl Into, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { let hir_id = self.last_node_with_lint_attrs; @@ -1142,9 +1134,7 @@ impl LintContext for EarlyContext<'_> { lint: &'static Lint, span: Option, msg: impl Into, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { self.builder.struct_lint(lint, span.map(|s| s.into()), msg, decorate) } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 4c7f9eeff8c28..b9add9e9f0657 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -45,13 +45,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { fn inlined_check_id(&mut self, id: ast::NodeId) { for early_lint in self.context.buffered.take(id) { let BufferedEarlyLint { span, msg, node_id: _, lint_id, diagnostic } = early_lint; - self.context.lookup_with_diagnostics( - lint_id.lint, - Some(span), - msg, - |lint| lint, - diagnostic, - ); + self.context.lookup_with_diagnostics(lint_id.lint, Some(span), msg, |_| {}, diagnostic); } } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index c1d4ed37627f2..bf3265f70dd2a 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -1077,7 +1077,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { GateIssue::Language, lint_from_cli, ); - lint }, ); return false; @@ -1104,9 +1103,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { lint: &'static Lint, span: Option, msg: impl Into, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { let (level, src) = self.lint_level(lint); struct_lint_level(self.sess, lint, level, src, span, msg, decorate) @@ -1121,7 +1118,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { ) { let (level, src) = self.lint_level(lint); struct_lint_level(self.sess, lint, level, src, Some(span), decorate.msg(), |lint| { - decorate.decorate_lint(lint) + decorate.decorate_lint(lint); }); } @@ -1129,7 +1126,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { pub fn emit_lint(&self, lint: &'static Lint, decorate: impl for<'a> DecorateLint<'a, ()>) { let (level, src) = self.lint_level(lint); struct_lint_level(self.sess, lint, level, src, None, decorate.msg(), |lint| { - decorate.decorate_lint(lint) + decorate.decorate_lint(lint); }); } } diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index f0e415492ae96..9fcd70ba0b569 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -126,7 +126,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc lint.note(fluent::lint_more_info_note); if !is_arg_inside_call(arg_span, span) { // No clue where this argument is coming from. - return lint; + return; } if arg_macro.is_some_and(|id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) { // A case of `panic!(format!(..))`. @@ -207,7 +207,6 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc } } } - lint }); } diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index eada116f89638..f9856c3f8b54b 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -284,9 +284,7 @@ pub fn struct_lint_level( src: LintLevelSource, span: Option, msg: impl Into, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { // Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to // the "real" work. @@ -298,12 +296,7 @@ pub fn struct_lint_level( src: LintLevelSource, span: Option, msg: impl Into, - decorate: Box< - dyn '_ - + for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, - >, + decorate: Box FnOnce(&'b mut DiagnosticBuilder<'a, ()>)>, ) { // Check for future incompatibility lints and issue a stronger warning. let future_incompatible = lint.future_incompatible; diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 564a1fad14dad..0cba6d5b52a8f 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -223,7 +223,6 @@ fn late_report_deprecation( let kind = tcx.def_descr(def_id); deprecation_suggestion(diag, kind, suggestion, method_span); } - diag }); } @@ -587,7 +586,7 @@ impl<'tcx> TyCtxt<'tcx> { unmarked: impl FnOnce(Span, DefId), ) -> bool { let soft_handler = |lint, span, msg: String| { - self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |lint| lint) + self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |_| {}) }; let eval_result = self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable); diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 34068a9da37e8..092b59deeff36 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -113,7 +113,7 @@ impl<'tcx> TyCtxt<'tcx> { self.local_def_id_to_hir_id(local_def_id), self.def_span(ct.def), "cannot use constants which depend on generic parameters in types", - |err| err, + |_| {}, ) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 5e61847a37a0e..9a48d1f038a55 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2030,7 +2030,7 @@ impl<'tcx> TyCtxt<'tcx> { let msg = decorator.msg(); let (level, src) = self.lint_level_at_node(lint, hir_id); struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, |diag| { - decorator.decorate_lint(diag) + decorator.decorate_lint(diag); }) } @@ -2047,9 +2047,7 @@ impl<'tcx> TyCtxt<'tcx> { hir_id: HirId, span: impl Into, msg: impl Into, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { let (level, src) = self.lint_level_at_node(lint, hir_id); struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate); @@ -2064,7 +2062,9 @@ impl<'tcx> TyCtxt<'tcx> { id: HirId, decorator: impl for<'a> DecorateLint<'a, ()>, ) { - self.struct_lint_node(lint, id, decorator.msg(), |diag| decorator.decorate_lint(diag)) + self.struct_lint_node(lint, id, decorator.msg(), |diag| { + decorator.decorate_lint(diag); + }) } /// Emit a lint at the appropriate level for a hir node. @@ -2079,9 +2079,7 @@ impl<'tcx> TyCtxt<'tcx> { lint: &'static Lint, id: HirId, msg: impl Into, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { let (level, src) = self.lint_level_at_node(lint, id); struct_lint_level(self.sess, lint, level, src, None, msg, decorate); diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 88ebea700210b..eb643ae14149f 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -273,7 +273,6 @@ fn overlap<'tcx>( causing the impls to overlap", infcx.resolve_vars_if_possible(failing_obligation.predicate) )); - lint }, ); } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index fbde7455145c2..e3f89b3f5f699 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -194,7 +194,6 @@ fn lint_object_unsafe_trait( // Only provide the help if its a local trait, otherwise it's not violation.solution().add_to(err); } - err }, ); } diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 39f5ff52eba69..71a88f5f07cb6 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -450,7 +450,6 @@ fn report_conflicting_impls<'tcx>( msg, |err| { decorate(tcx, &overlap, impl_span, err); - err }, ); } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 8215926ee331f..0150496990d2d 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -380,7 +380,9 @@ pub(crate) fn run_global_ctxt( crate::lint::MISSING_CRATE_LEVEL_DOCS, DocContext::as_local_hir_id(tcx, krate.module.item_id).unwrap(), "no documentation found for this crate's top-level module", - |lint| lint.help(help), + |lint| { + lint.help(help); + }, ); } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index dbd78ea0dc97c..6f667d18e355e 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -835,7 +835,7 @@ impl<'tcx> ExtraInfo<'tcx> { self.tcx.local_def_id_to_hir_id(def_id), self.sp, msg, - |l| l, + |_| {}, ); } } @@ -843,9 +843,7 @@ impl<'tcx> ExtraInfo<'tcx> { fn error_invalid_codeblock_attr_with_help( &self, msg: impl Into, - f: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + f: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { if let Some(def_id) = self.def_id.as_local() { self.tcx.struct_span_lint_hir( @@ -1296,7 +1294,7 @@ impl LangString { lint.help(format!( "there is an attribute with a similar name: `edition{}`", &x[4..], - )) + )); }, ); } @@ -1350,7 +1348,7 @@ impl LangString { lint.help(format!( "there is an attribute with a similar name: `{flag}`" )) - .help(help) + .help(help); }, ); } diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index 8d5b17f43cdcd..a931e8804d9cb 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -131,7 +131,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item hir_id, sp, "missing code example in this documentation", - |lint| lint, + |_| {}, ); } } else if tests.found_tests > 0 @@ -142,7 +142,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item hir_id, item.attr_span(cx.tcx), "documentation test in private item", - |lint| lint, + |_| {}, ); } } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 6b536e97c43cf..ee185ab98922d 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1755,8 +1755,6 @@ fn report_diagnostic( } decorate(lint, span, link_range); - - lint }); } diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs index 0c5cfffe1be53..bffa17da3b4c7 100644 --- a/src/librustdoc/passes/lint/bare_urls.rs +++ b/src/librustdoc/passes/lint/bare_urls.rs @@ -31,7 +31,7 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item) { "use an automatic link instead", format!("<{url}>"), Applicability::MachineApplicable, - ) + ); }); }; diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs index e9b9e36a53030..b5583ae45209f 100644 --- a/src/librustdoc/passes/lint/check_code_block_syntax.rs +++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs @@ -131,8 +131,6 @@ fn check_rust_syntax( for message in buffer.messages.iter() { lint.note(message.clone()); } - - lint }); } diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs index 4a80c22ed0851..90874c01102e5 100644 --- a/src/librustdoc/passes/lint/html_tags.rs +++ b/src/librustdoc/passes/lint/html_tags.rs @@ -89,7 +89,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<') || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>') { - return lint; + return; } // multipart form is chosen here because ``Vec`` would be confusing. lint.multipart_suggestion( @@ -101,8 +101,6 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { Applicability::MaybeIncorrect, ); } - - lint }); }; diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs index 472781e7d2294..4491d20b478d0 100644 --- a/src/librustdoc/passes/lint/redundant_explicit_links.rs +++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs @@ -181,8 +181,6 @@ fn check_inline_or_reference_unknown_redundancy( .span_label(display_span, "because label contains path that resolves to same destination") .note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links") .span_suggestion_with_style(link_span, "remove explicit link target", format!("[{}]", link_data.display_link), Applicability::MaybeIncorrect, SuggestionStyle::ShowAlways); - - lint }); } @@ -234,8 +232,6 @@ fn check_reference_redundancy( .span_note(def_span, "referenced explicit link target defined here") .note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links") .span_suggestion_with_style(link_span, "remove explicit link target", format!("[{}]", link_data.display_link), Applicability::MaybeIncorrect, SuggestionStyle::ShowAlways); - - lint }); } diff --git a/src/librustdoc/passes/lint/unescaped_backticks.rs b/src/librustdoc/passes/lint/unescaped_backticks.rs index 8b7fdd6ab1f93..0893cd0b40b52 100644 --- a/src/librustdoc/passes/lint/unescaped_backticks.rs +++ b/src/librustdoc/passes/lint/unescaped_backticks.rs @@ -111,8 +111,6 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { } suggest_insertion(cx, item, &dox, lint, backtick_index, '\\', "if you meant to use a literal backtick, escape it"); - - lint }); } Event::Code(_) => { diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs index fa56e5b0ba2bd..7562961538e30 100644 --- a/src/tools/clippy/clippy_utils/src/diagnostics.rs +++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs @@ -49,7 +49,6 @@ pub fn span_lint(cx: &T, lint: &'static Lint, sp: impl Into( diag.help(help.to_string()); } docs_link(diag, lint); - diag }); } @@ -134,7 +132,6 @@ pub fn span_lint_and_note( diag.note(note); } docs_link(diag, lint); - diag }); } @@ -152,7 +149,6 @@ where cx.struct_span_lint(lint, sp, msg.to_string(), |diag| { f(diag); docs_link(diag, lint); - diag }); } @@ -160,7 +156,6 @@ pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, s #[expect(clippy::disallowed_methods)] cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| { docs_link(diag, lint); - diag }); } @@ -176,7 +171,6 @@ pub fn span_lint_hir_and_then( cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| { f(diag); docs_link(diag, lint); - diag }); } From 252d99a54b44208295d5f6eb6f6443e65acbd0dd Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 15 Dec 2023 16:08:26 +0000 Subject: [PATCH 05/12] Fix comments --- compiler/rustc_lint/src/context.rs | 9 --------- compiler/rustc_lint/src/levels.rs | 2 -- compiler/rustc_middle/src/lint.rs | 25 +++---------------------- compiler/rustc_middle/src/ty/context.rs | 4 ---- 4 files changed, 3 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 6def7218fff8e..c7a9d5e80aca6 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -520,9 +520,6 @@ pub trait LintContext { /// Emit a lint at the appropriate level, with an optional associated span and an existing /// diagnostic. /// - /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed - /// explanation. - /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] fn lookup_with_diagnostics( @@ -984,8 +981,6 @@ pub trait LintContext { // set the span in their `decorate` function (preferably using set_span). /// Emit a lint at the appropriate level, with an optional associated span. /// - /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. - /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] fn lookup>( @@ -1011,8 +1006,6 @@ pub trait LintContext { /// Emit a lint at the appropriate level, with an associated span. /// - /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. - /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] fn struct_span_lint>( @@ -1035,8 +1028,6 @@ pub trait LintContext { /// Emit a lint at the appropriate level, with no associated span. /// - /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. - /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] fn lint( diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index bf3265f70dd2a..8c8ff3fc65064 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -1093,8 +1093,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { /// Used to emit a lint-related diagnostic based on the current state of /// this lint context. /// - /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. - /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] #[track_caller] diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index f9856c3f8b54b..4c4f38d1ad8cf 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -253,29 +253,10 @@ pub fn explain_lint_level_source( /// - [`TyCtxt::struct_lint_node`] /// - `LintContext::lookup` /// -/// ## `decorate` signature +/// ## `decorate` /// -/// The return value of `decorate` is ignored by this function. So what is the -/// point of returning `&'b mut DiagnosticBuilder<'a, ()>`? -/// -/// There are 2 reasons for this signature. -/// -/// First of all, it prevents accidental use of `.emit()` -- it's clear that the -/// builder will be later used and shouldn't be emitted right away (this is -/// especially important because the old API expected you to call `.emit()` in -/// the closure). -/// -/// Second of all, it makes the most common case of adding just a single label -/// /suggestion much nicer, since [`DiagnosticBuilder`] methods return -/// `&mut DiagnosticBuilder`, you can just chain methods, without needed -/// awkward `{ ...; }`: -/// ```ignore pseudo-code -/// struct_lint_level( -/// ..., -/// |lint| lint.span_label(sp, "lbl") -/// // ^^^^^^^^^^^^^^^^^^^^^ returns `&mut DiagnosticBuilder` by default -/// ) -/// ``` +/// It is not intended to call `emit`/`cancel` on the `DiagnosticBuilder` passed +/// in the `decorate` callback. #[track_caller] pub fn struct_lint_level( sess: &Session, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 9a48d1f038a55..6a6ed59fabfa9 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2036,8 +2036,6 @@ impl<'tcx> TyCtxt<'tcx> { /// Emit a lint at the appropriate level for a hir node, with an associated span. /// - /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. - /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] #[track_caller] @@ -2069,8 +2067,6 @@ impl<'tcx> TyCtxt<'tcx> { /// Emit a lint at the appropriate level for a hir node. /// - /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. - /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] #[track_caller] From ad00641b7466bc8887706f5bca1cb7952a0ea3b0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 23 Nov 2023 04:45:42 +0000 Subject: [PATCH 06/12] Collect lang items from AST --- compiler/rustc_ast_lowering/src/lib.rs | 1 + compiler/rustc_passes/src/lang_items.rs | 370 +++++++++++------- compiler/rustc_passes/src/weak_lang_items.rs | 30 +- tests/ui/duplicate_entry_error.stderr | 7 +- tests/ui/error-codes/E0152.stderr | 2 +- tests/ui/error-codes/E0264.stderr | 2 +- .../lang-item-generic-requirements.rs | 3 + .../lang-item-generic-requirements.stderr | 37 +- .../panic-handler-duplicate.stderr | 12 +- .../ui/panic-handler/panic-handler-std.stderr | 6 +- tests/ui/traits/issue-102989.rs | 1 + tests/ui/traits/issue-102989.stderr | 22 +- 12 files changed, 320 insertions(+), 173 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index d9663d50c595c..1a252520177e0 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -453,6 +453,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> { tcx.ensure_with_value().output_filenames(()); tcx.ensure_with_value().early_lint_checks(()); tcx.ensure_with_value().debugger_visualizers(LOCAL_CRATE); + tcx.ensure_with_value().get_lang_items(()); let (mut resolver, krate) = tcx.resolver_for_lowering(()).steal(); let ast_index = index_crate(&resolver.node_id_to_def_id, &krate); diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index 83b7d8d71bc85..536d5b46fcbe6 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -7,18 +7,18 @@ //! * Traits that represent operators; e.g., `Add`, `Sub`, `Index`. //! * Functions called by the compiler itself. -use crate::check_attr::target_from_impl_item; use crate::errors::{ DuplicateLangItem, IncorrectTarget, LangItemOnIncorrectTarget, UnknownLangItem, }; use crate::weak_lang_items; -use rustc_hir as hir; -use rustc_hir::def::DefKind; +use rustc_ast as ast; +use rustc_ast::visit; +use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::{extract, GenericRequirement}; -use rustc_hir::{LangItem, LanguageItems, Target}; -use rustc_middle::ty::TyCtxt; +use rustc_hir::{LangItem, LanguageItems, MethodKind, Target}; +use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_session::cstore::ExternCrate; use rustc_span::symbol::kw::Empty; use rustc_span::Span; @@ -31,28 +31,55 @@ pub(crate) enum Duplicate { CrateDepends, } -struct LanguageItemCollector<'tcx> { +struct LanguageItemCollector<'ast, 'tcx> { items: LanguageItems, tcx: TyCtxt<'tcx>, + resolver: &'ast ResolverAstLowering, + // FIXME(#118552): We should probably feed def_span eagerly on def-id creation + // so we can avoid constructing this map for local def-ids. + item_spans: FxHashMap, + parent_item: Option<&'ast ast::Item>, } -impl<'tcx> LanguageItemCollector<'tcx> { - fn new(tcx: TyCtxt<'tcx>) -> LanguageItemCollector<'tcx> { - LanguageItemCollector { tcx, items: LanguageItems::new() } +impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> { + fn new( + tcx: TyCtxt<'tcx>, + resolver: &'ast ResolverAstLowering, + ) -> LanguageItemCollector<'ast, 'tcx> { + LanguageItemCollector { + tcx, + resolver, + items: LanguageItems::new(), + item_spans: FxHashMap::default(), + parent_item: None, + } } - fn check_for_lang(&mut self, actual_target: Target, def_id: LocalDefId) { - let attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id)); - if let Some((name, span)) = extract(attrs) { + fn check_for_lang( + &mut self, + actual_target: Target, + def_id: LocalDefId, + attrs: &'ast [ast::Attribute], + item_span: Span, + generics: Option<&'ast ast::Generics>, + ) { + if let Some((name, attr_span)) = extract(attrs) { match LangItem::from_name(name) { // Known lang item with attribute on correct target. Some(lang_item) if actual_target == lang_item.target() => { - self.collect_item_extended(lang_item, def_id, span); + self.collect_item_extended( + lang_item, + def_id, + item_span, + attr_span, + generics, + actual_target, + ); } // Known lang item with attribute on incorrect target. Some(lang_item) => { self.tcx.sess.emit_err(LangItemOnIncorrectTarget { - span, + span: attr_span, name, expected_target: lang_item.target(), actual_target, @@ -60,127 +87,123 @@ impl<'tcx> LanguageItemCollector<'tcx> { } // Unknown lang item. _ => { - self.tcx.sess.emit_err(UnknownLangItem { span, name }); + self.tcx.sess.emit_err(UnknownLangItem { span: attr_span, name }); } } } } - fn collect_item(&mut self, lang_item: LangItem, item_def_id: DefId) { + fn collect_item(&mut self, lang_item: LangItem, item_def_id: DefId, item_span: Option) { // Check for duplicates. - if let Some(original_def_id) = self.items.get(lang_item) { - if original_def_id != item_def_id { - let local_span = self.tcx.hir().span_if_local(item_def_id); - let lang_item_name = lang_item.name(); - let crate_name = self.tcx.crate_name(item_def_id.krate); - let mut dependency_of = Empty; - let is_local = item_def_id.is_local(); - let path = if is_local { - String::new() - } else { - self.tcx - .crate_extern_paths(item_def_id.krate) - .iter() - .map(|p| p.display().to_string()) - .collect::>() - .join(", ") - }; - let first_defined_span = self.tcx.hir().span_if_local(original_def_id); - let mut orig_crate_name = Empty; - let mut orig_dependency_of = Empty; - let orig_is_local = original_def_id.is_local(); - let orig_path = if orig_is_local { - String::new() - } else { - self.tcx - .crate_extern_paths(original_def_id.krate) - .iter() - .map(|p| p.display().to_string()) - .collect::>() - .join(", ") - }; - if first_defined_span.is_none() { - orig_crate_name = self.tcx.crate_name(original_def_id.krate); - if let Some(ExternCrate { dependency_of: inner_dependency_of, .. }) = - self.tcx.extern_crate(original_def_id) - { - orig_dependency_of = self.tcx.crate_name(*inner_dependency_of); - } + if let Some(original_def_id) = self.items.get(lang_item) + && original_def_id != item_def_id + { + let lang_item_name = lang_item.name(); + let crate_name = self.tcx.crate_name(item_def_id.krate); + let mut dependency_of = Empty; + let is_local = item_def_id.is_local(); + let path = if is_local { + String::new() + } else { + self.tcx + .crate_extern_paths(item_def_id.krate) + .iter() + .map(|p| p.display().to_string()) + .collect::>() + .join(", ") + }; + + let first_defined_span = self.item_spans.get(&original_def_id).copied(); + let mut orig_crate_name = Empty; + let mut orig_dependency_of = Empty; + let orig_is_local = original_def_id.is_local(); + let orig_path = if orig_is_local { + String::new() + } else { + self.tcx + .crate_extern_paths(original_def_id.krate) + .iter() + .map(|p| p.display().to_string()) + .collect::>() + .join(", ") + }; + + if first_defined_span.is_none() { + orig_crate_name = self.tcx.crate_name(original_def_id.krate); + if let Some(ExternCrate { dependency_of: inner_dependency_of, .. }) = + self.tcx.extern_crate(original_def_id) + { + orig_dependency_of = self.tcx.crate_name(*inner_dependency_of); } + } - let duplicate = if local_span.is_some() { - Duplicate::Plain - } else { - match self.tcx.extern_crate(item_def_id) { - Some(ExternCrate { dependency_of: inner_dependency_of, .. }) => { - dependency_of = self.tcx.crate_name(*inner_dependency_of); - Duplicate::CrateDepends - } - _ => Duplicate::Crate, + let duplicate = if item_span.is_some() { + Duplicate::Plain + } else { + match self.tcx.extern_crate(item_def_id) { + Some(ExternCrate { dependency_of: inner_dependency_of, .. }) => { + dependency_of = self.tcx.crate_name(*inner_dependency_of); + Duplicate::CrateDepends } - }; - - self.tcx.sess.emit_err(DuplicateLangItem { - local_span, - lang_item_name, - crate_name, - dependency_of, - is_local, - path, - first_defined_span, - orig_crate_name, - orig_dependency_of, - orig_is_local, - orig_path, - duplicate, - }); + _ => Duplicate::Crate, + } + }; + + self.tcx.sess.emit_err(DuplicateLangItem { + local_span: item_span, + lang_item_name, + crate_name, + dependency_of, + is_local, + path, + first_defined_span, + orig_crate_name, + orig_dependency_of, + orig_is_local, + orig_path, + duplicate, + }); + } else { + // Matched. + self.items.set(lang_item, item_def_id); + // Collect span for error later + if let Some(item_span) = item_span { + self.item_spans.insert(item_def_id, item_span); } } - - // Matched. - self.items.set(lang_item, item_def_id); } // Like collect_item() above, but also checks whether the lang item is declared // with the right number of generic arguments. - fn collect_item_extended(&mut self, lang_item: LangItem, item_def_id: LocalDefId, span: Span) { + fn collect_item_extended( + &mut self, + lang_item: LangItem, + item_def_id: LocalDefId, + item_span: Span, + attr_span: Span, + generics: Option<&'ast ast::Generics>, + target: Target, + ) { let name = lang_item.name(); - // Now check whether the lang_item has the expected number of generic - // arguments. Generally speaking, binary and indexing operations have - // one (for the RHS/index), unary operations have none, the closure - // traits have one for the argument list, coroutines have one for the - // resume argument, and ordering/equality relations have one for the RHS - // Some other types like Box and various functions like drop_in_place - // have minimum requirements. + if let Some(generics) = generics { + // Now check whether the lang_item has the expected number of generic + // arguments. Generally speaking, binary and indexing operations have + // one (for the RHS/index), unary operations have none, the closure + // traits have one for the argument list, coroutines have one for the + // resume argument, and ordering/equality relations have one for the RHS + // Some other types like Box and various functions like drop_in_place + // have minimum requirements. - if let hir::Node::Item(hir::Item { kind, span: item_span, .. }) = - self.tcx.hir_node_by_def_id(item_def_id) - { - let (actual_num, generics_span) = match kind.generics() { - Some(generics) => ( - generics - .params - .iter() - .filter(|p| { - !matches!( - p.kind, - hir::GenericParamKind::Const { is_host_effect: true, .. } - ) - }) - .count(), - generics.span, - ), - None => (0, *item_span), - }; + let actual_num = generics.params.len(); let mut at_least = false; let required = match lang_item.required_generics() { GenericRequirement::Exact(num) if num != actual_num => Some(num), GenericRequirement::Minimum(num) if actual_num < num => { at_least = true; - Some(num)} - , + Some(num) + } // If the number matches, or there is no requirement, handle it normally _ => None, }; @@ -190,10 +213,10 @@ impl<'tcx> LanguageItemCollector<'tcx> { // item kind of the target is correct, the target is still wrong // because of the wrong number of generic arguments. self.tcx.sess.emit_err(IncorrectTarget { - span, - generics_span, + span: attr_span, + generics_span: generics.span, name: name.as_str(), - kind: kind.descr(), + kind: target.name(), num, actual_num, at_least, @@ -204,58 +227,117 @@ impl<'tcx> LanguageItemCollector<'tcx> { } } - self.collect_item(lang_item, item_def_id.to_def_id()); + self.collect_item(lang_item, item_def_id.to_def_id(), Some(item_span)); } } /// Traverses and collects all the lang items in all crates. fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems { + let resolver = tcx.resolver_for_lowering(()).borrow(); + let (resolver, krate) = &*resolver; + // Initialize the collector. - let mut collector = LanguageItemCollector::new(tcx); + let mut collector = LanguageItemCollector::new(tcx, resolver); // Collect lang items in other crates. for &cnum in tcx.crates(()).iter() { for &(def_id, lang_item) in tcx.defined_lang_items(cnum).iter() { - collector.collect_item(lang_item, def_id); + collector.collect_item(lang_item, def_id, None); } } - // Collect lang items in this crate. - let crate_items = tcx.hir_crate_items(()); + // Collect lang items local to this crate. + visit::Visitor::visit_crate(&mut collector, krate); - for id in crate_items.items() { - collector - .check_for_lang(Target::from_def_kind(tcx.def_kind(id.owner_id)), id.owner_id.def_id); + // Find all required but not-yet-defined lang items. + weak_lang_items::check_crate(tcx, &mut collector.items, krate); - if matches!(tcx.def_kind(id.owner_id), DefKind::Enum) { - let item = tcx.hir().item(id); - if let hir::ItemKind::Enum(def, ..) = &item.kind { - for variant in def.variants { - collector.check_for_lang(Target::Variant, variant.def_id); - } - } - } - } + // Return all the lang items that were found. + collector.items +} + +impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> { + fn visit_item(&mut self, i: &'ast ast::Item) { + let (target, generics) = match &i.kind { + ast::ItemKind::ExternCrate(_) => (Target::ExternCrate, None), + ast::ItemKind::Use(_) => (Target::Use, None), + ast::ItemKind::Static(_) => (Target::Static, None), + ast::ItemKind::Const(ct) => (Target::Const, Some(&ct.generics)), + ast::ItemKind::Fn(fun) => (Target::Fn, Some(&fun.generics)), + ast::ItemKind::Mod(_, _) => (Target::Mod, None), + ast::ItemKind::ForeignMod(_) => (Target::ForeignFn, None), + ast::ItemKind::GlobalAsm(_) => (Target::GlobalAsm, None), + ast::ItemKind::TyAlias(alias) => (Target::TyAlias, Some(&alias.generics)), + ast::ItemKind::Enum(_, generics) => (Target::Enum, Some(generics)), + ast::ItemKind::Struct(_, generics) => (Target::Struct, Some(generics)), + ast::ItemKind::Union(_, generics) => (Target::Union, Some(generics)), + ast::ItemKind::Trait(tr) => (Target::Trait, Some(&tr.generics)), + ast::ItemKind::TraitAlias(generics, _) => (Target::TraitAlias, Some(generics)), + ast::ItemKind::Impl(_) => (Target::Impl, None), + ast::ItemKind::MacroDef(_) => (Target::MacroDef, None), + ast::ItemKind::MacCall(_) => unreachable!("macros should have been expanded"), + }; - // FIXME: avoid calling trait_item() when possible - for id in crate_items.trait_items() { - let item = tcx.hir().trait_item(id); - collector.check_for_lang(Target::from_trait_item(item), item.owner_id.def_id) + self.check_for_lang( + target, + self.resolver.node_id_to_def_id[&i.id], + &i.attrs, + i.span, + generics, + ); + + let parent_item = self.parent_item.replace(i); + visit::walk_item(self, i); + self.parent_item = parent_item; } - // FIXME: avoid calling impl_item() when possible - for id in crate_items.impl_items() { - let item = tcx.hir().impl_item(id); - collector.check_for_lang(target_from_impl_item(tcx, item), item.owner_id.def_id) + fn visit_enum_def(&mut self, enum_definition: &'ast ast::EnumDef) { + for variant in &enum_definition.variants { + self.check_for_lang( + Target::Variant, + self.resolver.node_id_to_def_id[&variant.id], + &variant.attrs, + variant.span, + None, + ); + } + + visit::walk_enum_def(self, enum_definition); } - // Extract out the found lang items. - let LanguageItemCollector { mut items, .. } = collector; + fn visit_assoc_item(&mut self, i: &'ast ast::AssocItem, ctxt: visit::AssocCtxt) { + let (target, generics) = match &i.kind { + ast::AssocItemKind::Fn(fun) => ( + match &self.parent_item.unwrap().kind { + ast::ItemKind::Impl(i) => { + if i.of_trait.is_some() { + Target::Method(MethodKind::Trait { body: fun.body.is_some() }) + } else { + Target::Method(MethodKind::Inherent) + } + } + ast::ItemKind::Trait(_) => { + Target::Method(MethodKind::Trait { body: fun.body.is_some() }) + } + _ => unreachable!(), + }, + &fun.generics, + ), + ast::AssocItemKind::Const(ct) => (Target::AssocConst, &ct.generics), + ast::AssocItemKind::Type(ty) => (Target::AssocTy, &ty.generics), + ast::AssocItemKind::MacCall(_) => unreachable!("macros should have been expanded"), + }; - // Find all required but not-yet-defined lang items. - weak_lang_items::check_crate(tcx, &mut items); + self.check_for_lang( + target, + self.resolver.node_id_to_def_id[&i.id], + &i.attrs, + i.span, + Some(generics), + ); - items + visit::walk_assoc_item(self, i, ctxt); + } } pub fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs index 9a6fb88c28110..b226c65e96c88 100644 --- a/compiler/rustc_passes/src/weak_lang_items.rs +++ b/compiler/rustc_passes/src/weak_lang_items.rs @@ -1,5 +1,7 @@ //! Validity checking for weak lang items +use rustc_ast as ast; +use rustc_ast::visit; use rustc_data_structures::fx::FxHashSet; use rustc_hir::lang_items::{self, LangItem}; use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS; @@ -11,7 +13,7 @@ use crate::errors::{MissingLangItem, MissingPanicHandler, UnknownExternLangItem} /// Checks the crate for usage of weak lang items, returning a vector of all the /// language items required by this crate, but not defined yet. -pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) { +pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems, krate: &ast::Crate) { // These are never called by user code, they're generated by the compiler. // They will never implicitly be added to the `missing` array unless we do // so here. @@ -22,24 +24,30 @@ pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) { items.missing.push(LangItem::EhCatchTypeinfo); } - let crate_items = tcx.hir_crate_items(()); - for id in crate_items.foreign_items() { - let attrs = tcx.hir().attrs(id.hir_id()); - if let Some((lang_item, _)) = lang_items::extract(attrs) { + visit::Visitor::visit_crate(&mut WeakLangItemVisitor { tcx, items }, krate); + + verify(tcx, items); +} + +struct WeakLangItemVisitor<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + items: &'a mut lang_items::LanguageItems, +} + +impl<'ast> visit::Visitor<'ast> for WeakLangItemVisitor<'_, '_> { + fn visit_foreign_item(&mut self, i: &'ast ast::ForeignItem) { + if let Some((lang_item, _)) = lang_items::extract(&i.attrs) { if let Some(item) = LangItem::from_name(lang_item) && item.is_weak() { - if items.get(item).is_none() { - items.missing.push(item); + if self.items.get(item).is_none() { + self.items.missing.push(item); } } else { - let span = tcx.def_span(id.owner_id); - tcx.sess.emit_err(UnknownExternLangItem { span, lang_item }); + self.tcx.sess.emit_err(UnknownExternLangItem { span: i.span, lang_item }); } } } - - verify(tcx, items); } fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) { diff --git a/tests/ui/duplicate_entry_error.stderr b/tests/ui/duplicate_entry_error.stderr index 592640a884c9a..3b5998df353c4 100644 --- a/tests/ui/duplicate_entry_error.stderr +++ b/tests/ui/duplicate_entry_error.stderr @@ -1,8 +1,11 @@ error[E0152]: found duplicate lang item `panic_impl` --> $DIR/duplicate_entry_error.rs:11:1 | -LL | fn panic_impl(info: &PanicInfo) -> ! { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / fn panic_impl(info: &PanicInfo) -> ! { +LL | | +LL | | loop {} +LL | | } + | |_^ | = note: the lang item is first defined in crate `std` (which `duplicate_entry_error` depends on) = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib diff --git a/tests/ui/error-codes/E0152.stderr b/tests/ui/error-codes/E0152.stderr index 816ba2d569b6b..dbea7e6d27fbe 100644 --- a/tests/ui/error-codes/E0152.stderr +++ b/tests/ui/error-codes/E0152.stderr @@ -2,7 +2,7 @@ error[E0152]: found duplicate lang item `owned_box` --> $DIR/E0152.rs:5:1 | LL | struct Foo(T); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ | = note: the lang item is first defined in crate `alloc` (which `std` depends on) = note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rlib diff --git a/tests/ui/error-codes/E0264.stderr b/tests/ui/error-codes/E0264.stderr index 14a4ffbe31666..3503fb229e4f3 100644 --- a/tests/ui/error-codes/E0264.stderr +++ b/tests/ui/error-codes/E0264.stderr @@ -2,7 +2,7 @@ error[E0264]: unknown external lang item: `cake` --> $DIR/E0264.rs:5:5 | LL | fn cake(); - | ^^^^^^^^^ + | ^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/lang-items/lang-item-generic-requirements.rs b/tests/ui/lang-items/lang-item-generic-requirements.rs index 3d33adf68316b..21bd7187e15b4 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.rs +++ b/tests/ui/lang-items/lang-item-generic-requirements.rs @@ -22,6 +22,8 @@ trait MyIndex<'a, T> {} #[lang = "phantom_data"] //~^ ERROR `phantom_data` language item must be applied to a struct with 1 generic argument struct MyPhantomData; +//~^ ERROR parameter `T` is never used +//~| ERROR parameter `U` is never used #[lang = "owned_box"] //~^ ERROR `owned_box` language item must be applied to a struct with at least 1 generic argument @@ -40,6 +42,7 @@ fn ice() { let r = 5; let a = 6; r + a; + //~^ ERROR cannot add `{integer}` to `{integer}` // Use drop in place my_ptr_drop(); diff --git a/tests/ui/lang-items/lang-item-generic-requirements.stderr b/tests/ui/lang-items/lang-item-generic-requirements.stderr index 4d349a25f9c2a..8072e6797e49c 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.stderr +++ b/tests/ui/lang-items/lang-item-generic-requirements.stderr @@ -33,7 +33,7 @@ LL | struct MyPhantomData; | ------ this struct has 2 generic arguments error[E0718]: `owned_box` language item must be applied to a struct with at least 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:26:1 + --> $DIR/lang-item-generic-requirements.rs:28:1 | LL | #[lang = "owned_box"] | ^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | struct Foo; | - this struct has 0 generic arguments error[E0718]: `start` language item must be applied to a function with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:32:1 + --> $DIR/lang-item-generic-requirements.rs:34:1 | LL | #[lang = "start"] | ^^^^^^^^^^^^^^^^^ @@ -50,6 +50,35 @@ LL | LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize { | - this function has 0 generic arguments -error: aborting due to 6 previous errors +error[E0392]: parameter `T` is never used + --> $DIR/lang-item-generic-requirements.rs:24:22 + | +LL | struct MyPhantomData; + | ^ unused parameter + | + = help: consider removing `T` or referring to it in a field + = help: if you intended `T` to be a const parameter, use `const T: usize` instead + +error[E0392]: parameter `U` is never used + --> $DIR/lang-item-generic-requirements.rs:24:25 + | +LL | struct MyPhantomData; + | ^ unused parameter + | + = help: consider removing `U` or referring to it in a field + = help: if you intended `U` to be a const parameter, use `const U: usize` instead + +error[E0369]: cannot add `{integer}` to `{integer}` + --> $DIR/lang-item-generic-requirements.rs:44:7 + | +LL | r + a; + | - ^ - {integer} + | | + | {integer} + +error: requires `copy` lang_item + +error: aborting due to 10 previous errors -For more information about this error, try `rustc --explain E0718`. +Some errors have detailed explanations: E0369, E0392, E0718. +For more information about an error, try `rustc --explain E0369`. diff --git a/tests/ui/panic-handler/panic-handler-duplicate.stderr b/tests/ui/panic-handler/panic-handler-duplicate.stderr index 5c50b7016b20d..299847474cd58 100644 --- a/tests/ui/panic-handler/panic-handler-duplicate.stderr +++ b/tests/ui/panic-handler/panic-handler-duplicate.stderr @@ -1,14 +1,18 @@ error[E0152]: found duplicate lang item `panic_impl` --> $DIR/panic-handler-duplicate.rs:15:1 | -LL | fn panic2(info: &PanicInfo) -> ! { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / fn panic2(info: &PanicInfo) -> ! { +LL | | loop {} +LL | | } + | |_^ | note: the lang item is first defined here --> $DIR/panic-handler-duplicate.rs:10:1 | -LL | fn panic(info: &PanicInfo) -> ! { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / fn panic(info: &PanicInfo) -> ! { +LL | | loop {} +LL | | } + | |_^ error: aborting due to 1 previous error diff --git a/tests/ui/panic-handler/panic-handler-std.stderr b/tests/ui/panic-handler/panic-handler-std.stderr index ad9addec8eb4d..48c216ce27ec4 100644 --- a/tests/ui/panic-handler/panic-handler-std.stderr +++ b/tests/ui/panic-handler/panic-handler-std.stderr @@ -1,8 +1,10 @@ error[E0152]: found duplicate lang item `panic_impl` --> $DIR/panic-handler-std.rs:8:1 | -LL | fn panic(info: PanicInfo) -> ! { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / fn panic(info: PanicInfo) -> ! { +LL | | loop {} +LL | | } + | |_^ | = note: the lang item is first defined in crate `std` (which `panic_handler_std` depends on) = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib diff --git a/tests/ui/traits/issue-102989.rs b/tests/ui/traits/issue-102989.rs index 216cd78e56f9a..f1ecee0a552a7 100644 --- a/tests/ui/traits/issue-102989.rs +++ b/tests/ui/traits/issue-102989.rs @@ -7,6 +7,7 @@ trait Sized { } //~ ERROR found duplicate lang item `sized` fn ref_Struct(self: &Struct, f: &u32) -> &u32 { //~^ ERROR `self` parameter is only allowed in associated functions //~| ERROR cannot find type `Struct` in this scope + //~| ERROR mismatched types let x = x << 1; //~^ ERROR cannot find value `x` in this scope } diff --git a/tests/ui/traits/issue-102989.stderr b/tests/ui/traits/issue-102989.stderr index 7d0098fe88502..40e49df2b2d96 100644 --- a/tests/ui/traits/issue-102989.stderr +++ b/tests/ui/traits/issue-102989.stderr @@ -13,7 +13,7 @@ LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | ^^^^^^ not found in this scope error[E0425]: cannot find value `x` in this scope - --> $DIR/issue-102989.rs:10:13 + --> $DIR/issue-102989.rs:11:13 | LL | let x = x << 1; | ^ help: a local variable with a similar name exists: `f` @@ -22,13 +22,27 @@ error[E0152]: found duplicate lang item `sized` --> $DIR/issue-102989.rs:5:1 | LL | trait Sized { } - | ^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ | = note: the lang item is first defined in crate `core` (which `std` depends on) = note: first definition in `core` loaded from SYSROOT/libcore-*.rlib = note: second definition in the local crate (`issue_102989`) -error: aborting due to 4 previous errors +error[E0308]: mismatched types + --> $DIR/issue-102989.rs:7:42 + | +LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 { + | ---------- ^^^^ expected `&u32`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + | +help: consider returning the local binding `f` + | +LL ~ let x = x << 1; +LL + f + | + +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0152, E0412, E0425. +Some errors have detailed explanations: E0152, E0308, E0412, E0425. For more information about an error, try `rustc --explain E0152`. From fc010de26b998e02323955914f0df6614f29816b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 23 Nov 2023 04:55:03 +0000 Subject: [PATCH 07/12] banish hir::GenericBound::LangItemTrait --- compiler/rustc_ast_lowering/src/lib.rs | 43 ++++++++++++++++--- .../src/diagnostics/region_name.rs | 30 +++++-------- compiler/rustc_hir/src/hir.rs | 3 -- compiler/rustc_hir/src/intravisit.rs | 4 -- .../rustc_hir_analysis/src/astconv/bounds.rs | 11 ----- .../rustc_hir_analysis/src/astconv/mod.rs | 37 +--------------- .../src/collect/resolve_bound_vars.rs | 26 ----------- compiler/rustc_hir_pretty/src/lib.rs | 5 --- .../src/fn_ctxt/suggestions.rs | 6 +-- .../src/infer/error_reporting/suggest.rs | 26 ++++------- compiler/rustc_passes/src/hir_stats.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 10 ++++- 12 files changed, 68 insertions(+), 135 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 1a252520177e0..5c9e43f1e064c 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -766,6 +766,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.resolver.get_import_res(id).present_items() } + fn make_lang_item_path( + &mut self, + lang_item: hir::LangItem, + span: Span, + args: Option<&'hir hir::GenericArgs<'hir>>, + ) -> &'hir hir::Path<'hir> { + let def_id = self.tcx.require_lang_item(lang_item, Some(span)); + let def_kind = self.tcx.def_kind(def_id); + let res = Res::Def(def_kind, def_id); + self.arena.alloc(hir::Path { + span, + res, + segments: self.arena.alloc_from_iter([hir::PathSegment { + ident: Ident::new(lang_item.name(), span), + hir_id: self.next_id(), + res, + args, + infer_args: false, + }]), + }) + } + /// Reuses the span but adds information like the kind of the desugaring and features that are /// allowed inside this span. fn mark_span_with_reason( @@ -1977,18 +1999,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator), }; - let future_args = self.arena.alloc(hir::GenericArgs { + let bound_args = self.arena.alloc(hir::GenericArgs { args: &[], bindings: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)], parenthesized: hir::GenericArgsParentheses::No, span_ext: DUMMY_SP, }); - hir::GenericBound::LangItemTrait( - trait_lang_item, - opaque_ty_span, - self.next_id(), - future_args, + hir::GenericBound::Trait( + hir::PolyTraitRef { + bound_generic_params: &[], + trait_ref: hir::TraitRef { + path: self.make_lang_item_path( + trait_lang_item, + opaque_ty_span, + Some(bound_args), + ), + hir_ref_id: self.next_id(), + }, + span: opaque_ty_span, + }, + hir::TraitBoundModifier::None, ) } diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 4c3cef2e76315..8441dfaa7df28 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -788,28 +788,18 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { }; let opaque_ty = hir.item(id); if let hir::ItemKind::OpaqueTy(hir::OpaqueTy { - bounds: - [ - hir::GenericBound::LangItemTrait( - hir::LangItem::Future, - _, - _, - hir::GenericArgs { - bindings: - [ - hir::TypeBinding { - ident: Ident { name: sym::Output, .. }, - kind: - hir::TypeBindingKind::Equality { term: hir::Term::Ty(ty) }, - .. - }, - ], - .. - }, - ), - ], + bounds: [hir::GenericBound::Trait(trait_ref, _)], .. }) = opaque_ty.kind + && let Some(segment) = trait_ref.trait_ref.path.segments.last() + && let Some(args) = segment.args + && let [ + hir::TypeBinding { + ident: Ident { name: sym::Output, .. }, + kind: hir::TypeBindingKind::Equality { term: hir::Term::Ty(ty) }, + .. + }, + ] = args.bindings { ty } else { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 01508375b1ace..9f82e14df053f 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -435,8 +435,6 @@ pub enum TraitBoundModifier { #[derive(Clone, Copy, Debug, HashStable_Generic)] pub enum GenericBound<'hir> { Trait(PolyTraitRef<'hir>, TraitBoundModifier), - // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem` - LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>), Outlives(&'hir Lifetime), } @@ -451,7 +449,6 @@ impl GenericBound<'_> { pub fn span(&self) -> Span { match self { GenericBound::Trait(t, ..) => t.span, - GenericBound::LangItemTrait(_, span, ..) => *span, GenericBound::Outlives(l) => l.ident.span, } } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 9cf1db166a581..67e058a3219ec 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1075,10 +1075,6 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericB GenericBound::Trait(ref typ, _modifier) => { visitor.visit_poly_trait_ref(typ); } - GenericBound::LangItemTrait(_, _span, hir_id, args) => { - visitor.visit_id(hir_id); - visitor.visit_generic_args(args); - } GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime), } } diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs index dfec3c5e829a6..0748644cc0ab9 100644 --- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs +++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs @@ -134,17 +134,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { only_self_bounds, ); } - &hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => { - self.instantiate_lang_item_trait_ref( - lang_item, - span, - hir_id, - args, - param_ty, - bounds, - only_self_bounds, - ); - } hir::GenericBound::Outlives(lifetime) => { let region = self.ast_region_to_region(lifetime, None); bounds.push_region_bound( diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index caae6fa4f065e..0758a41b3d4f5 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -791,6 +791,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {}); self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false); + // TODO: inline self.instantiate_poly_trait_ref_inner( hir_id, span, @@ -809,42 +810,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) } - pub(crate) fn instantiate_lang_item_trait_ref( - &self, - lang_item: hir::LangItem, - span: Span, - hir_id: hir::HirId, - args: &GenericArgs<'_>, - self_ty: Ty<'tcx>, - bounds: &mut Bounds<'tcx>, - only_self_bounds: OnlySelfBounds, - ) { - let binding_span = Some(span); - let constness = ty::BoundConstness::NotConst; - let speculative = false; - let trait_ref_span = span; - let trait_def_id = self.tcx().require_lang_item(lang_item, Some(span)); - let trait_segment = &hir::PathSegment::invalid(); - let infer_args = false; - - self.instantiate_poly_trait_ref_inner( - hir_id, - span, - binding_span, - constness, - ty::ImplPolarity::Positive, - bounds, - speculative, - trait_ref_span, - trait_def_id, - trait_segment, - args, - infer_args, - self_ty, - only_self_bounds, - ); - } - fn ast_path_to_mono_trait_ref( &self, span: Span, diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index a972c51e3eea0..13c1373db82df 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -938,32 +938,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } } - fn visit_param_bound(&mut self, bound: &'tcx hir::GenericBound<'tcx>) { - match bound { - hir::GenericBound::LangItemTrait(_, _, hir_id, _) => { - // FIXME(jackh726): This is pretty weird. `LangItemTrait` doesn't go - // through the regular poly trait ref code, so we don't get another - // chance to introduce a binder. For now, I'm keeping the existing logic - // of "if there isn't a Binder scope above us, add one", but I - // imagine there's a better way to go about this. - let (binders, scope_type) = self.poly_trait_ref_binder_info(); - - self.record_late_bound_vars(*hir_id, binders); - let scope = Scope::Binder { - hir_id: *hir_id, - bound_vars: FxIndexMap::default(), - s: self.scope, - scope_type, - where_bound_origin: None, - }; - self.with(scope, |this| { - intravisit::walk_param_bound(this, bound); - }); - } - _ => intravisit::walk_param_bound(self, bound), - } - } - fn visit_poly_trait_ref(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) { self.visit_poly_trait_ref_inner(trait_ref, NonLifetimeBinderAllowed::Allow); } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 8701626058d43..a92d31b0870d7 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -2088,11 +2088,6 @@ impl<'a> State<'a> { } self.print_poly_trait_ref(tref); } - GenericBound::LangItemTrait(lang_item, span, ..) => { - self.word("#[lang = \""); - self.print_ident(Ident::new(lang_item.name(), *span)); - self.word("\"]"); - } GenericBound::Outlives(lt) => { self.print_lifetime(lt); } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 28f377083f68f..7363a3c215687 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -825,9 +825,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let hir::Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(op_ty), .. }) = self.tcx.hir_node(item_id.hir_id()) - && let [ - hir::GenericBound::LangItemTrait(hir::LangItem::Future, _, _, generic_args), - ] = op_ty.bounds + && let [hir::GenericBound::Trait(trait_ref, _)] = op_ty.bounds + && let Some(hir::PathSegment { args: Some(generic_args), .. }) = + trait_ref.trait_ref.path.segments.last() && let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(term) } = ty_binding.kind diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index b762778122ba4..bbe07b8ed72b2 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -668,26 +668,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ( hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: last_bounds, .. }), hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: exp_bounds, .. }), - ) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| { - match (left, right) { - ( - hir::GenericBound::Trait(tl, ml), - hir::GenericBound::Trait(tr, mr), - ) if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id() + ) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| match ( + left, right, + ) { + (hir::GenericBound::Trait(tl, ml), hir::GenericBound::Trait(tr, mr)) + if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id() && ml == mr => - { - true - } - ( - hir::GenericBound::LangItemTrait(langl, _, _, argsl), - hir::GenericBound::LangItemTrait(langr, _, _, argsr), - ) if langl == langr => { - // FIXME: consider the bounds! - debug!("{:?} {:?}", argsl, argsr); - true - } - _ => false, + { + true } + _ => false, }) => { StatementAsExpression::NeedsBoxing diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 85969b72d2397..c2392620cb285 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -429,7 +429,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { fn visit_param_bound(&mut self, b: &'v hir::GenericBound<'v>) { record_variants!( (self, b, b, Id::None, hir, GenericBound, GenericBound), - [Trait, LangItemTrait, Outlives] + [Trait, Outlives] ); hir_visit::walk_param_bound(self, b) } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 9073cd6ac47a1..c3f97e34e3919 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -4783,8 +4783,14 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>( }; let future = tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty(); - let Some(hir::GenericBound::LangItemTrait(_, _, _, generics)) = future.bounds.get(0) else { - // `async fn` should always lower to a lang item bound... but don't ICE. + let [hir::GenericBound::Trait(trait_ref, _)] = future.bounds else { + // `async fn` should always lower to a single bound... but don't ICE. + return None; + }; + let Some(hir::PathSegment { args: Some(generics), .. }) = + trait_ref.trait_ref.path.segments.last() + else { + // desugaring to a single path segment for `Future<...>`. return None; }; let Some(hir::TypeBindingKind::Equality { term: hir::Term::Ty(future_output_ty) }) = From 653ca5ad3bbaa59f663ecbc9f2ebac7a8077478e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 23 Nov 2023 05:34:29 +0000 Subject: [PATCH 08/12] Simplify instantiate_poly_trait_ref --- .../rustc_hir_analysis/src/astconv/mod.rs | 110 ++++++------------ 1 file changed, 35 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 0758a41b3d4f5..af2ef57214773 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -675,36 +675,57 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) } - fn instantiate_poly_trait_ref_inner( + /// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct + /// a full trait reference. The resulting trait reference is returned. This may also generate + /// auxiliary bounds, which are added to `bounds`. + /// + /// Example: + /// + /// ```ignore (illustrative) + /// poly_trait_ref = Iterator + /// self_ty = Foo + /// ``` + /// + /// this would return `Foo: Iterator` and add `::Item = u32` into `bounds`. + /// + /// **A note on binders:** against our usual convention, there is an implied binder around + /// the `self_ty` and `poly_trait_ref` parameters here. So they may reference bound regions. + /// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>` + /// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be + /// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly, + /// however. + #[instrument(level = "debug", skip(self, span, constness, bounds, speculative))] + pub(crate) fn instantiate_poly_trait_ref( &self, - hir_id: hir::HirId, + trait_ref: &hir::TraitRef<'_>, span: Span, - binding_span: Option, constness: ty::BoundConstness, polarity: ty::ImplPolarity, + self_ty: Ty<'tcx>, bounds: &mut Bounds<'tcx>, speculative: bool, - trait_ref_span: Span, - trait_def_id: DefId, - trait_segment: &hir::PathSegment<'_>, - args: &GenericArgs<'_>, - infer_args: bool, - self_ty: Ty<'tcx>, only_self_bounds: OnlySelfBounds, ) -> GenericArgCountResult { + let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()); + let trait_segment = trait_ref.path.segments.last().unwrap(); + let args = trait_segment.args(); + + self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {}); + self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false); + let (generic_args, arg_count) = self.create_args_for_ast_path( - trait_ref_span, + trait_ref.path.span, trait_def_id, &[], trait_segment, args, - infer_args, + trait_segment.infer_args, Some(self_ty), constness, ); let tcx = self.tcx(); - let bound_vars = tcx.late_bound_vars(hir_id); + let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id); debug!(?bound_vars); let assoc_bindings = self.create_assoc_bindings_for_generic_args(args); @@ -732,13 +753,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // Specify type to assert that error was already reported in `Err` case. let _: Result<_, ErrorGuaranteed> = self.add_predicates_for_ast_type_binding( - hir_id, + trait_ref.hir_ref_id, poly_trait_ref, binding, bounds, speculative, &mut dup_bindings, - binding_span.unwrap_or(binding.span), + binding.span, constness, only_self_bounds, polarity, @@ -749,67 +770,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { arg_count } - /// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct - /// a full trait reference. The resulting trait reference is returned. This may also generate - /// auxiliary bounds, which are added to `bounds`. - /// - /// Example: - /// - /// ```ignore (illustrative) - /// poly_trait_ref = Iterator - /// self_ty = Foo - /// ``` - /// - /// this would return `Foo: Iterator` and add `::Item = u32` into `bounds`. - /// - /// **A note on binders:** against our usual convention, there is an implied bounder around - /// the `self_ty` and `poly_trait_ref` parameters here. So they may reference bound regions. - /// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>` - /// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be - /// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly, - /// however. - #[instrument(level = "debug", skip(self, span, constness, bounds, speculative))] - pub(crate) fn instantiate_poly_trait_ref( - &self, - trait_ref: &hir::TraitRef<'_>, - span: Span, - constness: ty::BoundConstness, - polarity: ty::ImplPolarity, - self_ty: Ty<'tcx>, - bounds: &mut Bounds<'tcx>, - speculative: bool, - only_self_bounds: OnlySelfBounds, - ) -> GenericArgCountResult { - let hir_id = trait_ref.hir_ref_id; - let binding_span = None; - let trait_ref_span = trait_ref.path.span; - let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()); - let trait_segment = trait_ref.path.segments.last().unwrap(); - let args = trait_segment.args(); - let infer_args = trait_segment.infer_args; - - self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {}); - self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false); - - // TODO: inline - self.instantiate_poly_trait_ref_inner( - hir_id, - span, - binding_span, - constness, - polarity, - bounds, - speculative, - trait_ref_span, - trait_def_id, - trait_segment, - args, - infer_args, - self_ty, - only_self_bounds, - ) - } - fn ast_path_to_mono_trait_ref( &self, span: Span, From 553c3c44b2620a87a25e260ed69e1e508adad6fa Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 28 Nov 2023 00:59:51 +0000 Subject: [PATCH 09/12] Appease the tools: clippy, rustdoc --- src/librustdoc/clean/mod.rs | 16 ---------------- src/tools/clippy/clippy_lints/src/len_zero.rs | 10 ++++++---- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6631c42727099..b11bddbbdfe3d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -184,22 +184,6 @@ fn clean_generic_bound<'tcx>( ) -> Option { Some(match *bound { hir::GenericBound::Outlives(lt) => GenericBound::Outlives(clean_lifetime(lt, cx)), - hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => { - let def_id = cx.tcx.require_lang_item(lang_item, Some(span)); - - let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(cx.tcx, def_id)); - - let generic_args = clean_generic_args(generic_args, cx); - let GenericArgs::AngleBracketed { bindings, .. } = generic_args else { - bug!("clean: parenthesized `GenericBound::LangItemTrait`"); - }; - - let trait_ = clean_trait_ref_with_bindings(cx, trait_ref, bindings); - GenericBound::TraitBound( - PolyTrait { trait_, generic_params: vec![] }, - hir::TraitBoundModifier::None, - ) - } hir::GenericBound::Trait(ref t, modifier) => { // `T: ~const Destruct` is hidden because `T: Destruct` is a no-op. if modifier == hir::TraitBoundModifier::MaybeConst diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index 83af551fcd3ca..8c032b1702360 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -8,8 +8,8 @@ use rustc_hir::def::Res; use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::{ AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, ImplItem, ImplItemKind, - ImplicitSelfKind, Item, ItemKind, LangItem, Mutability, Node, PatKind, PathSegment, PrimTy, QPath, TraitItemRef, - TyKind, TypeBindingKind, + ImplicitSelfKind, Item, ItemKind, Mutability, Node, PatKind, PathSegment, PrimTy, QPath, TraitItemRef, + TyKind, TypeBindingKind, OpaqueTyOrigin, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, AssocKind, FnSig, Ty}; @@ -289,8 +289,10 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<& kind: ItemKind::OpaqueTy(opaque), .. } = item - && opaque.bounds.len() == 1 - && let GenericBound::LangItemTrait(LangItem::Future, _, _, generic_args) = &opaque.bounds[0] + && let OpaqueTyOrigin::AsyncFn(_) = opaque.origin + && let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds + && let Some(segment) = trait_ref.trait_ref.path.segments.last() + && let Some(generic_args) = segment.args && generic_args.bindings.len() == 1 && let TypeBindingKind::Equality { term: From 04fafd69dec85b02338cf303a21df93ad9594fa1 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Wed, 2 Nov 2022 10:47:00 -0500 Subject: [PATCH 10/12] Cfg remove lang items in doctest --- library/std/src/panicking.rs | 4 ++-- library/std/src/process.rs | 2 +- library/std/src/rt.rs | 2 +- library/std/src/sys/personality/mod.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 55f4917a93705..66b4ec37c8ec5 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -588,7 +588,7 @@ pub fn panicking() -> bool { } /// Entry point of panics from the core crate (`panic_impl` lang item). -#[cfg(not(test))] +#[cfg(not(any(test, doctest)))] #[panic_handler] pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { struct FormatStringPayload<'a> { @@ -669,7 +669,7 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { /// panic!() and assert!(). In particular, this is the only entry point that supports /// arbitrary payloads, not just format strings. #[unstable(feature = "libstd_sys_internals", reason = "used by the panic! macro", issue = "none")] -#[cfg_attr(not(test), lang = "begin_panic")] +#[cfg_attr(not(any(test, doctest)), lang = "begin_panic")] // lang item for CTFE panic support // never inline unless panic_immediate_abort to avoid code // bloat at the call sites as much as possible diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 6004ed51bd164..4a7f5d8e0bee6 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -2311,7 +2311,7 @@ pub fn id() -> u32 { /// of the `main` function, this trait is likely to be available only on /// standard library's runtime for convenience. Other runtimes are not required /// to provide similar functionality. -#[cfg_attr(not(test), lang = "termination")] +#[cfg_attr(not(any(test, doctest)), lang = "termination")] #[stable(feature = "termination_trait_lib", since = "1.61.0")] #[rustc_on_unimplemented(on( cause = "MainFunctionType", diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs index f1eeb75be7c4d..335944845ae0b 100644 --- a/library/std/src/rt.rs +++ b/library/std/src/rt.rs @@ -154,7 +154,7 @@ fn lang_start_internal( ret_code } -#[cfg(not(test))] +#[cfg(not(any(test, doctest)))] #[lang = "start"] fn lang_start( main: fn() -> T, diff --git a/library/std/src/sys/personality/mod.rs b/library/std/src/sys/personality/mod.rs index 0fff53f18875b..d37b8ce634654 100644 --- a/library/std/src/sys/personality/mod.rs +++ b/library/std/src/sys/personality/mod.rs @@ -12,7 +12,7 @@ mod dwarf; -#[cfg(not(test))] +#[cfg(not(any(test, doctest)))] cfg_if::cfg_if! { if #[cfg(target_os = "emscripten")] { mod emcc; From bc1ca6b52854d09cfdcb83d0559f3e72720aa41f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 9 Dec 2023 17:27:18 +0000 Subject: [PATCH 11/12] Fix enforcement of generics for associated items --- compiler/rustc_ast/src/ast.rs | 22 ++++++++++++ compiler/rustc_hir/src/target.rs | 36 +++++++++++++++++++ compiler/rustc_passes/src/lang_items.rs | 46 +++++++++++++++---------- 3 files changed, 85 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 5755ae8a8bc47..9d543563c0f96 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2845,6 +2845,28 @@ impl Item { pub fn span_with_attributes(&self) -> Span { self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span)) } + + pub fn opt_generics(&self) -> Option<&Generics> { + match &self.kind { + ItemKind::ExternCrate(_) + | ItemKind::Use(_) + | ItemKind::Mod(_, _) + | ItemKind::ForeignMod(_) + | ItemKind::GlobalAsm(_) + | ItemKind::MacCall(_) + | ItemKind::MacroDef(_) => None, + ItemKind::Static(_) => None, + ItemKind::Const(i) => Some(&i.generics), + ItemKind::Fn(i) => Some(&i.generics), + ItemKind::TyAlias(i) => Some(&i.generics), + ItemKind::TraitAlias(generics, _) + | ItemKind::Enum(_, generics) + | ItemKind::Struct(_, generics) + | ItemKind::Union(_, generics) => Some(&generics), + ItemKind::Trait(i) => Some(&i.generics), + ItemKind::Impl(i) => Some(&i.generics), + } + } } /// `extern` qualifier on a function item or function type. diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index 0d65ddb5642af..8948a03e4a6f8 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -67,6 +67,42 @@ impl Display for Target { } impl Target { + pub fn is_associated_item(self) -> bool { + match self { + Target::AssocConst | Target::AssocTy | Target::Method(_) => true, + Target::ExternCrate + | Target::Use + | Target::Static + | Target::Const + | Target::Fn + | Target::Closure + | Target::Mod + | Target::ForeignMod + | Target::GlobalAsm + | Target::TyAlias + | Target::OpaqueTy + | Target::Enum + | Target::Variant + | Target::Struct + | Target::Field + | Target::Union + | Target::Trait + | Target::TraitAlias + | Target::Impl + | Target::Expression + | Target::Statement + | Target::Arm + | Target::ForeignFn + | Target::ForeignStatic + | Target::ForeignTy + | Target::GenericParam(_) + | Target::MacroDef + | Target::Param + | Target::PatField + | Target::ExprField => false, + } + } + pub fn from_item(item: &Item<'_>) -> Target { match item.kind { ItemKind::ExternCrate(..) => Target::ExternCrate, diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index 536d5b46fcbe6..6d14a14096d0b 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -195,7 +195,15 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> { // Some other types like Box and various functions like drop_in_place // have minimum requirements. - let actual_num = generics.params.len(); + // FIXME: This still doesn't count, e.g., elided lifetimes and APITs. + let mut actual_num = generics.params.len(); + if target.is_associated_item() { + actual_num += self + .parent_item + .unwrap() + .opt_generics() + .map_or(0, |generics| generics.params.len()); + } let mut at_least = false; let required = match lang_item.required_generics() { @@ -258,23 +266,23 @@ fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems { impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> { fn visit_item(&mut self, i: &'ast ast::Item) { - let (target, generics) = match &i.kind { - ast::ItemKind::ExternCrate(_) => (Target::ExternCrate, None), - ast::ItemKind::Use(_) => (Target::Use, None), - ast::ItemKind::Static(_) => (Target::Static, None), - ast::ItemKind::Const(ct) => (Target::Const, Some(&ct.generics)), - ast::ItemKind::Fn(fun) => (Target::Fn, Some(&fun.generics)), - ast::ItemKind::Mod(_, _) => (Target::Mod, None), - ast::ItemKind::ForeignMod(_) => (Target::ForeignFn, None), - ast::ItemKind::GlobalAsm(_) => (Target::GlobalAsm, None), - ast::ItemKind::TyAlias(alias) => (Target::TyAlias, Some(&alias.generics)), - ast::ItemKind::Enum(_, generics) => (Target::Enum, Some(generics)), - ast::ItemKind::Struct(_, generics) => (Target::Struct, Some(generics)), - ast::ItemKind::Union(_, generics) => (Target::Union, Some(generics)), - ast::ItemKind::Trait(tr) => (Target::Trait, Some(&tr.generics)), - ast::ItemKind::TraitAlias(generics, _) => (Target::TraitAlias, Some(generics)), - ast::ItemKind::Impl(_) => (Target::Impl, None), - ast::ItemKind::MacroDef(_) => (Target::MacroDef, None), + let target = match &i.kind { + ast::ItemKind::ExternCrate(_) => Target::ExternCrate, + ast::ItemKind::Use(_) => Target::Use, + ast::ItemKind::Static(_) => Target::Static, + ast::ItemKind::Const(_) => Target::Const, + ast::ItemKind::Fn(_) => Target::Fn, + ast::ItemKind::Mod(_, _) => Target::Mod, + ast::ItemKind::ForeignMod(_) => Target::ForeignFn, + ast::ItemKind::GlobalAsm(_) => Target::GlobalAsm, + ast::ItemKind::TyAlias(_) => Target::TyAlias, + ast::ItemKind::Enum(_, _) => Target::Enum, + ast::ItemKind::Struct(_, _) => Target::Struct, + ast::ItemKind::Union(_, _) => Target::Union, + ast::ItemKind::Trait(_) => Target::Trait, + ast::ItemKind::TraitAlias(_, _) => Target::TraitAlias, + ast::ItemKind::Impl(_) => Target::Impl, + ast::ItemKind::MacroDef(_) => Target::MacroDef, ast::ItemKind::MacCall(_) => unreachable!("macros should have been expanded"), }; @@ -283,7 +291,7 @@ impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> { self.resolver.node_id_to_def_id[&i.id], &i.attrs, i.span, - generics, + i.opt_generics(), ); let parent_item = self.parent_item.replace(i); From 47282799da75adc50a41a01402b4a1d4a056d69c Mon Sep 17 00:00:00 2001 From: Jakub Stasiak Date: Fri, 15 Dec 2023 20:53:14 +0100 Subject: [PATCH 12/12] Add link to is_benchmark from the Ipv6Addr::is_global documentation All other relevant is_* methods are mentioned in the list of addresses here, is_benchmarking has been the only one missing. --- library/core/src/net/ip_addr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index dafc58d3a7d91..8bf15c736c34b 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs @@ -1437,7 +1437,7 @@ impl Ipv6Addr { /// - The [unspecified address] ([`is_unspecified`](Ipv6Addr::is_unspecified)) /// - The [loopback address] ([`is_loopback`](Ipv6Addr::is_loopback)) /// - IPv4-mapped addresses - /// - Addresses reserved for benchmarking + /// - Addresses reserved for benchmarking ([`is_benchmarking`](Ipv6Addr::is_benchmarking)) /// - Addresses reserved for documentation ([`is_documentation`](Ipv6Addr::is_documentation)) /// - Unique local addresses ([`is_unique_local`](Ipv6Addr::is_unique_local)) /// - Unicast addresses with link-local scope ([`is_unicast_link_local`](Ipv6Addr::is_unicast_link_local))