Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
f6da035
Improve TLS codegen by marking the panic/init path as cold
orlp Jul 5, 2025
a528fbc
Also apply opt to OS-specific TLS impls
orlp Jul 5, 2025
8fd8fbf
Don't use inline(never)
orlp Jul 6, 2025
a7790c6
Rename Uninitialized to Unregistered
orlp Jun 5, 2026
2de39c0
Use zero to represent alive state for faster comparison on Arm
orlp Jun 5, 2026
3e1d6f8
Add `_value` API for number literals in proc-macro
GuillaumeGomez Mar 30, 2026
9fd93f4
Ignore `library/proc_macro/src/lib.rs` test on GCC backend due to pro…
GuillaumeGomez Mar 31, 2026
48c52ae
Put `f16` conversions behind a `cfg` check
GuillaumeGomez Jun 6, 2026
b791fd7
Fix diagnostics for non-exhaustive destructuring assignments
Jun 7, 2026
ba8e61e
test: remove ineffective link-extern-crate-with-drop-type test
arshalaromal Jun 8, 2026
4049f43
fix: don't suggest .into_iter() for .cloned()/.copied() on non-refere…
Albab-Hasan Jun 4, 2026
daaf367
explain that the size_of constant also serves to avoid optimizing awa…
RalfJung Jun 7, 2026
09c0629
rustdoc: Remove unnecessary fast path
fmease Jun 8, 2026
bde4379
Add field to distinguish const fns from always-const fns
oli-obk Jul 22, 2025
30451d6
Ignore diagnostic lines with a single "|"
zetanumbers Jun 2, 2026
322a540
Check comptime fns
oli-obk Jul 23, 2025
2a77be2
Prevent comptime fns from being called at runtime
oli-obk Nov 5, 2025
68890b7
Allow comptime fns to call other comptime fns
oli-obk Nov 5, 2025
406b8ef
Demonstrate that `const Trait` bounds allow trait methods to be calle…
oli-obk Nov 11, 2025
94e9c0b
Make the `inline` field on the `Const` `ConstContext` more clearly ta…
oli-obk Nov 11, 2025
4089c2a
Remove possibly footgunny `is_const` method
oli-obk May 3, 2026
768fc10
asm! support for the Xtensa architecture
MabezDev Oct 3, 2025
72cad5b
tests: codegen-llvm: Ignore BPF targets in c-variadic-opt
vadorovsky Jun 3, 2026
1fc09be
Relax test requirements for consistency
zetanumbers Jun 8, 2026
3cbe424
xfs support in test_rename_directory_to_non_empty_directory
Hoverbear May 19, 2026
de70798
Rollup merge of #147302 - esp-rs:xtensa-asm, r=Amanieu
JonathanBrouwer Jun 8, 2026
1419d3c
Rollup merge of #148820 - oli-obk:comptime, r=fee1-dead
JonathanBrouwer Jun 8, 2026
e2cb4a4
Rollup merge of #157299 - zetanumbers:fix-unstable-diagnostics-in-tes…
JonathanBrouwer Jun 8, 2026
7fc9526
Rollup merge of #143511 - orlp:tls-cold-init, r=joboet
JonathanBrouwer Jun 8, 2026
ab174b1
Rollup merge of #154608 - GuillaumeGomez:number_value_proc-macro_API,…
JonathanBrouwer Jun 8, 2026
fbe0e33
Rollup merge of #156762 - ferrocene:hoverbear/xfs-test-fix, r=Mark-Si…
JonathanBrouwer Jun 8, 2026
c603394
Rollup merge of #157300 - zetanumbers:fix-note-on-different-line-test…
JonathanBrouwer Jun 8, 2026
dcb272d
Rollup merge of #157383 - vadorovsky:vad/llvm-codegen-c-variadic-igno…
JonathanBrouwer Jun 8, 2026
4c561f2
Rollup merge of #157413 - Albab-Hasan:option-cloned-non-ref-diagnosti…
JonathanBrouwer Jun 8, 2026
7712e40
Rollup merge of #157578 - MaximilianAzendorf:issue-157553, r=Nadrieril
JonathanBrouwer Jun 8, 2026
c9da864
Rollup merge of #157587 - RalfJung:size-of-no-dce, r=oli-obk
JonathanBrouwer Jun 8, 2026
ab8dea7
Rollup merge of #157596 - arshalaromal:remove-ineffective-test, r=Jon…
JonathanBrouwer Jun 8, 2026
eb90e0a
Rollup merge of #157602 - fmease:rustdoc-rm-unnecessary-fast-path, r=…
JonathanBrouwer Jun 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions compiler/rustc_ast_lowering/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,17 @@ pub(crate) struct AwaitOnlyInAsyncFnAndBlocks {
pub item_span: Option<Span>,
}

#[derive(Diagnostic)]
#[diag("a function cannot be both `comptime` and `const`")]
pub(crate) struct ConstComptimeFn {
#[primary_span]
#[suggestion("remove the `const`", applicability = "machine-applicable", code = "")]
#[note("`const` implies the function can be called at runtime, too")]
pub span: Span,
#[label("`comptime` because of this")]
pub attr_span: Span,
}

#[derive(Diagnostic)]
#[diag("too many parameters for a coroutine (expected 0 or 1 parameters)", code = E0628)]
pub(crate) struct CoroutineTooManyParameters {
Expand Down
24 changes: 18 additions & 6 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use super::{
AstOwner, FnDeclKind, GenericArgsMode, ImplTraitContext, ImplTraitPosition, LoweringContext,
ParamMode, RelaxedBoundForbiddenReason, RelaxedBoundPolicy, ResolverAstLoweringExt,
};
use crate::diagnostics::ConstComptimeFn;

/// Wraps either IndexVec (during `hir_crate`), which acts like a primary
/// storage for most of the MaybeOwners, or FxIndexMap during delayed AST -> HIR
Expand Down Expand Up @@ -1773,12 +1774,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
safety.into()
};

hir::FnHeader {
safety,
asyncness,
constness: self.lower_constness(h.constness),
abi: self.lower_extern(h.ext),
let mut constness = self.lower_constness(h.constness);
if let Some(&attr_span) = find_attr!(attrs, RustcComptime(span) => span) {
match std::mem::replace(&mut constness, rustc_hir::Constness::Const { always: true }) {
rustc_hir::Constness::Const { always: true } => {
unreachable!("lower_constness cannot produce comptime")
}
// A function can't be `const` and `comptime` at the same time
rustc_hir::Constness::Const { always: false } => {
let Const::Yes(span) = h.constness else { unreachable!() };
self.dcx().emit_err(ConstComptimeFn { span, attr_span });
}
// Good
rustc_hir::Constness::NotConst => {}
}
}

hir::FnHeader { safety, asyncness, constness, abi: self.lower_extern(h.ext) }
}

pub(super) fn lower_abi(&mut self, abi_str: StrLit) -> ExternAbi {
Expand Down Expand Up @@ -1840,7 +1852,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

pub(super) fn lower_constness(&mut self, c: Const) -> hir::Constness {
match c {
Const::Yes(_) => hir::Constness::Const,
Const::Yes(_) => hir::Constness::Const { always: false },
Const::No => hir::Constness::NotConst,
}
}
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/semantics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,15 @@ impl NoArgsAttributeParser for MayDangleParser {
const STABILITY: AttributeStability = unstable!(dropck_eyepatch);
const CREATE: fn(span: Span) -> AttributeKind = AttributeKind::MayDangle;
}

pub(crate) struct ComptimeParser;
impl NoArgsAttributeParser for ComptimeParser {
const PATH: &[Symbol] = &[sym::rustc_comptime];
const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Fn),
]);
const STABILITY: AttributeStability = unstable!(rustc_attrs);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcComptime;
}
3 changes: 2 additions & 1 deletion compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ use crate::attributes::repr::*;
use crate::attributes::rustc_allocator::*;
use crate::attributes::rustc_dump::*;
use crate::attributes::rustc_internal::*;
use crate::attributes::semantics::*;
use crate::attributes::semantics::{ComptimeParser, *};
use crate::attributes::stability::*;
use crate::attributes::test_attrs::*;
use crate::attributes::traits::*;
Expand Down Expand Up @@ -234,6 +234,7 @@ attribute_parsers!(
Single<WithoutArgs<AutomaticallyDerivedParser>>,
Single<WithoutArgs<ColdParser>>,
Single<WithoutArgs<CompilerBuiltinsParser>>,
Single<WithoutArgs<ComptimeParser>>,
Single<WithoutArgs<ConstContinueParser>>,
Single<WithoutArgs<CoroutineParser>>,
Single<WithoutArgs<DefaultLibAllocatorParser>>,
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_codegen_gcc/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,11 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str {
| X86InlineAsmRegClass::mmx_reg
| X86InlineAsmRegClass::tmm_reg,
) => unreachable!("clobber-only"),
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::Xtensa(
XtensaInlineAsmRegClass::sreg | XtensaInlineAsmRegClass::breg,
) => unreachable!("clobber-only"),
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
bug!("GCC backend does not support SPIR-V")
}
Expand Down Expand Up @@ -872,6 +877,11 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
bug!("GCC backend does not support SPIR-V")
}
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::freg) => cx.type_f32(),
InlineAsmRegClass::Xtensa(
XtensaInlineAsmRegClass::sreg | XtensaInlineAsmRegClass::breg,
) => unreachable!("clobber-only"),
InlineAsmRegClass::Err => unreachable!(),
}
}
Expand Down Expand Up @@ -1070,6 +1080,7 @@ fn modifier_to_gcc(
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
bug!("LLVM backend does not support SPIR-V")
}
InlineAsmRegClass::Xtensa(_) => None,
InlineAsmRegClass::Err => unreachable!(),
}
}
12 changes: 12 additions & 0 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
}
InlineAsmArch::SpirV => {}
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {}
InlineAsmArch::Xtensa => {}
InlineAsmArch::Bpf => {}
InlineAsmArch::Msp430 => {
constraints.push("~{sr}".to_string());
Expand Down Expand Up @@ -740,6 +741,11 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
| X86InlineAsmRegClass::kreg0
| X86InlineAsmRegClass::tmm_reg,
) => unreachable!("clobber-only"),
Xtensa(XtensaInlineAsmRegClass::freg) => "f",
Xtensa(XtensaInlineAsmRegClass::reg) => "r",
Xtensa(XtensaInlineAsmRegClass::sreg | XtensaInlineAsmRegClass::breg) => {
unreachable!("clobber-only")
}
Wasm(WasmInlineAsmRegClass::local) => "r",
Bpf(BpfInlineAsmRegClass::reg) => "r",
Bpf(BpfInlineAsmRegClass::wreg) => "w",
Expand Down Expand Up @@ -845,6 +851,7 @@ fn modifier_to_llvm(
| X86InlineAsmRegClass::kreg0
| X86InlineAsmRegClass::tmm_reg,
) => unreachable!("clobber-only"),
Xtensa(_) => None,
Wasm(WasmInlineAsmRegClass::local) => None,
Bpf(_) => None,
Avr(AvrInlineAsmRegClass::reg_pair)
Expand Down Expand Up @@ -939,6 +946,11 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
| X86InlineAsmRegClass::kreg0
| X86InlineAsmRegClass::tmm_reg,
) => unreachable!("clobber-only"),
Xtensa(XtensaInlineAsmRegClass::reg) => cx.type_i32(),
Xtensa(XtensaInlineAsmRegClass::freg) => cx.type_f32(),
Xtensa(XtensaInlineAsmRegClass::sreg | XtensaInlineAsmRegClass::breg) => {
unreachable!("clobber-only")
}
Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
Bpf(BpfInlineAsmRegClass::reg) => cx.type_i64(),
Bpf(BpfInlineAsmRegClass::wreg) => cx.type_i32(),
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_const_eval/src/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// to do different checks than usual.

trace!("attempting to call a trait method");
let is_const = tcx.constness(callee) == hir::Constness::Const;
let is_const =
matches!(tcx.constness(callee), hir::Constness::Const { always: false });

// Only consider a trait to be const if the const conditions hold.
// Otherwise, it's really misleading to call something "conditionally"
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_const_eval/src/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,8 @@ fn build_error_for_const_call<'tcx>(
err.help("const traits are not yet supported on stable Rust");
}
}
} else if ccx.tcx.constness(callee) != hir::Constness::Const {
} else if !matches!(ccx.tcx.constness(callee), hir::Constness::Const { always: false })
{
let name = ccx.tcx.item_name(callee);
err.span_note(
ccx.tcx.def_span(callee),
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_const_eval/src/const_eval/fn_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Constness {
let node = tcx.hir_node_by_def_id(def_id);

match node {
Node::Ctor(VariantData::Tuple(..)) => Constness::Const,
Node::Ctor(VariantData::Tuple(..)) => Constness::Const { always: false },
Node::ForeignItem(item) if let ForeignItemKind::Fn(..) = item.kind => {
// Foreign functions cannot be evaluated at compile-time.
Constness::NotConst
}
Node::Expr(e) if let ExprKind::Closure(c) = e.kind => {
if let Constness::Const = c.constness && tcx.hir_body_const_context(tcx.local_parent(def_id)).is_none() {
if let Constness::Const { .. } = c.constness && tcx.hir_body_const_context(tcx.local_parent(def_id)).is_none() {
tcx.dcx().span_err(tcx.def_span(def_id), "cannot use `const` closures outside of const contexts");
return Constness::NotConst;
}
Expand All @@ -37,7 +37,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Constness {
..
}) => {
match sig.header.constness {
Constness::Const => Constness::Const,
Constness::Const { always } => Constness::Const { always },
// inherent impl could be const
Constness::NotConst => tcx.constness(tcx.local_parent(def_id)),
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ pub static BUILTIN_ATTRIBUTES: &[Symbol] = &[
sym::rustc_no_implicit_autorefs,
sym::rustc_coherence_is_core,
sym::rustc_coinductive,
sym::rustc_comptime,
sym::rustc_allow_incoherent_impl,
sym::rustc_preserve_ub_checks,
sym::rustc_deny_explicit_impl,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,8 @@ declare_features! (
(unstable, x87_target_feature, "1.85.0", Some(150261)),
/// Allows use of the `xop` target-feature
(unstable, xop_target_feature, "1.81.0", Some(127208)),
/// Allows use of the Xtensa target-features
(unstable, xtensa_target_feature, "CURRENT_RUSTC_VERSION", Some(157063)),
/// Allows `do yeet` expressions
(unstable, yeet_expr, "1.62.0", Some(96373)),
(unstable, yield_expr, "1.87.0", Some(43122)),
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1311,6 +1311,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_coinductive]`.
RustcCoinductive,

/// Represents `#[rustc_comptime]`
RustcComptime(Span),

/// Represents `#[rustc_confusables]`.
RustcConfusables {
confusables: ThinVec<Symbol>,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/attrs/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ impl AttributeKind {
RustcClean { .. } => No,
RustcCoherenceIsCore => No,
RustcCoinductive => No,
RustcComptime(..) => No, // Encoded directly in signature
RustcConfusables { .. } => Yes,
RustcConstStability { .. } => Yes,
RustcConstStableIndirect => No,
Expand Down
29 changes: 17 additions & 12 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2467,10 +2467,12 @@ pub enum ConstContext {
/// - Array length expressions
/// - Enum discriminants
/// - Const generics
///
/// For the most part, other contexts are treated just like a regular `const`, so they are
/// lumped into the same category.
Const { inline: bool },
Const {
/// For backwards compatibility `const` items allow
/// calls to `const fn` to get promoted.
/// We forbid that in comptime fns and inline consts.
allow_const_fn_promotion: bool,
},
}

impl ConstContext {
Expand Down Expand Up @@ -4632,17 +4634,24 @@ impl fmt::Display for Safety {
}

#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, StableHash)]
#[derive(Default)]
pub enum Constness {
#[default]
Const,
Const { always: bool },
NotConst,
}

/// This impl exists as an optimization so that metadata deserialization can
/// store the value directly and not have to encode it wrapped in another `Option`.
impl Default for Constness {
fn default() -> Self {
Self::Const { always: false }
}
}

impl fmt::Display for Constness {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match *self {
Self::Const => "const",
Self::Const { always: true } => "comptime",
Self::Const { always: false } => "const",
Self::NotConst => "non-const",
})
}
Expand Down Expand Up @@ -4696,10 +4705,6 @@ impl FnHeader {
matches!(self.asyncness, IsAsync::Async(_))
}

pub fn is_const(&self) -> bool {
matches!(self.constness, Constness::Const)
}

pub fn is_unsafe(&self) -> bool {
self.safety().is_unsafe()
}
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ impl<'a> State<'a> {

match of_trait {
None => {
if let hir::Constness::Const = constness {
if let hir::Constness::Const { always: false } = constness {
self.word_nbsp("const");
}
impl_generics(self)
Expand All @@ -733,7 +733,7 @@ impl<'a> State<'a> {

impl_generics(self);

if let hir::Constness::Const = constness {
if let hir::Constness::Const { always: false } = constness {
self.word_nbsp("const");
}

Expand Down Expand Up @@ -2623,7 +2623,8 @@ impl<'a> State<'a> {
fn print_constness(&mut self, s: hir::Constness) {
match s {
hir::Constness::NotConst => {}
hir::Constness::Const => self.word_nbsp("const"),
hir::Constness::Const { always: false } => self.word_nbsp("const"),
hir::Constness::Const { always: true } => { /* printed as an attribute */ }
}
}

Expand Down
13 changes: 12 additions & 1 deletion compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
callee_did: DefId,
callee_args: GenericArgsRef<'tcx>,
) {
let const_context = self.tcx.hir_body_const_context(self.body_id);

if let hir::Constness::Const { always: true } = self.tcx.constness(callee_did) {
match const_context {
Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => {}
Some(hir::ConstContext::ConstFn) | None => {
self.dcx().span_err(span, "comptime fns can only be called at compile time");
}
}
}

// FIXME(const_trait_impl): We should be enforcing these effects unconditionally.
// This can be done as soon as we convert the standard library back to
// using const traits, since if we were to enforce these conditions now,
Expand All @@ -1037,7 +1048,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return;
}

let host = match self.tcx.hir_body_const_context(self.body_id) {
let host = match const_context {
Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => {
ty::BoundConstness::Const
}
Expand Down
24 changes: 24 additions & 0 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"`count` is defined on `{iterator_trait}`, which `{rcvr_ty}` does not implement"
));
}
} else if matches!(item_ident.name.as_str(), "cloned" | "copied")
&& let ty::Adt(adt_def, args) = rcvr_ty.kind()
&& tcx.is_diagnostic_item(sym::Option, adt_def.did())
&& let inner_ty = args.type_at(0)
// Skip refs (`Option<&T>.into_iter().cloned()` is valid, let the default branch
// handle it), and params/infer where we can't statically rule out a reference.
&& !matches!(inner_ty.kind(), ty::Ref(..) | ty::Param(_) | ty::Infer(_))
{
// The default branch below would suggest `.into_iter()`, but that still
// fails: `Option<T>` yields `T` by value, not `&T`, so `.cloned()`/`.copied()`
// can't resolve. Give a targeted diagnostic instead.
err.span_label(span, format!("this method is only available on `Option<&_>`"));
if let SelfSource::MethodCall(rcvr_expr) = source
&& !span.in_external_macro(tcx.sess.source_map())
{
let call_expr = self.tcx.hir_expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id));
err.span_suggestion(
rcvr_expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi()),
format!("consider removing the `.{}()` call", item_ident.name),
"",
Applicability::MaybeIncorrect,
);
}
return Err(());
} else if self.impl_into_iterator_should_be_iterator(rcvr_ty, span, unsatisfied_predicates)
{
err.span_label(span, format!("`{rcvr_ty}` is not an iterator"));
Expand Down
Loading
Loading