diff options
Diffstat (limited to 'compiler')
93 files changed, 1023 insertions, 532 deletions
diff --git a/compiler/rustc_abi/src/canon_abi.rs b/compiler/rustc_abi/src/canon_abi.rs index 2cf7648a859..03eeb645489 100644 --- a/compiler/rustc_abi/src/canon_abi.rs +++ b/compiler/rustc_abi/src/canon_abi.rs @@ -50,18 +50,10 @@ pub enum CanonAbi { impl fmt::Display for CanonAbi { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.to_erased_extern_abi().as_str().fmt(f) - } -} - -impl CanonAbi { - /// convert to the ExternAbi that *shares a string* with this CanonAbi - /// - /// A target-insensitive mapping of CanonAbi to ExternAbi, convenient for "forwarding" impls. - /// Importantly, the set of CanonAbi values is a logical *subset* of ExternAbi values, - /// so this is injective: if you take an ExternAbi to a CanonAbi and back, you have lost data. - const fn to_erased_extern_abi(self) -> ExternAbi { - match self { + // convert to the ExternAbi that *shares a string* with this CanonAbi. + // FIXME: ideally we'd avoid printing `CanonAbi`, and preserve `ExternAbi` everywhere + // that we need to generate error messages. + let erased_abi = match self { CanonAbi::C => ExternAbi::C { unwind: false }, CanonAbi::Rust => ExternAbi::Rust, CanonAbi::RustCold => ExternAbi::RustCold, @@ -87,7 +79,8 @@ impl CanonAbi { X86Call::Vectorcall => ExternAbi::Vectorcall { unwind: false }, X86Call::Win64 => ExternAbi::Win64 { unwind: false }, }, - } + }; + erased_abi.as_str().fmt(f) } } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index f41627e479f..3004be40334 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -732,7 +732,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { 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_id = self.tcx.require_lang_item(lang_item, span); let def_kind = self.tcx.def_kind(def_id); let res = Res::Def(def_kind, def_id); self.arena.alloc(hir::Path { @@ -1406,7 +1406,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi(); let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }; - (region, LifetimeSyntax::Hidden) + (region, LifetimeSyntax::Implicit) } }; self.lower_lifetime(®ion, LifetimeSource::Reference, syntax) @@ -1790,7 +1790,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { id, Ident::new(kw::UnderscoreLifetime, span), LifetimeSource::Path { angle_brackets }, - LifetimeSyntax::Hidden, + LifetimeSyntax::Implicit, ) } @@ -2422,7 +2422,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Ident::new(kw::UnderscoreLifetime, self.lower_span(span)), hir::LifetimeKind::ImplicitObjectLifetimeDefault, LifetimeSource::Other, - LifetimeSyntax::Hidden, + LifetimeSyntax::Implicit, ); debug!("elided_dyn_bound: r={:?}", r); self.arena.alloc(r) diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index f45cf984f71..bf18e10e19f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -74,7 +74,7 @@ pub(crate) trait AttributeParser: Default + 'static { pub(crate) trait SingleAttributeParser: 'static { const PATH: &'static [Symbol]; - /// Caled when a duplicate attribute is found. + /// Called when a duplicate attribute is found. /// /// `first_span` is the span of the first occurrence of this attribute. // FIXME(jdonszelmann): default error diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 63bccf52018..15037e802ff 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -1,31 +1,38 @@ //! Centralized logic for parsing and attributes. //! -//! Part of a series of crates: -//! - rustc_attr_data_structures: contains types that the parsers parse into -//! - rustc_attr_parsing: this crate -//! - (in the future): rustc_attr_validation +//! ## Architecture +//! This crate is part of a series of crates that handle attribute processing. +//! - [rustc_attr_data_structures](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_data_structures/index.html): Defines the data structures that store parsed attributes +//! - [rustc_attr_parsing](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html): This crate, handles the parsing of attributes +//! - (planned) rustc_attr_validation: Will handle attribute validation //! -//! History: Check out [#131229](https://github.com/rust-lang/rust/issues/131229). -//! There used to be only one definition of attributes in the compiler: `ast::Attribute`. -//! These were then parsed or validated or both in places distributed all over the compiler. -//! This was a mess... +//! The separation between data structures and parsing follows the principle of separation of concerns. +//! Data structures (`rustc_attr_data_structures`) define what attributes look like after parsing. +//! This crate (`rustc_attr_parsing`) handles how to convert raw tokens into those structures. +//! This split allows other parts of the compiler to use the data structures without needing +//! the parsing logic, making the codebase more modular and maintainable. //! -//! Attributes are markers on items. -//! Many of them are actually attribute-like proc-macros, and are expanded to some other rust syntax. -//! This could either be a user provided proc macro, or something compiler provided. -//! `derive` is an example of one that the compiler provides. -//! These are built-in, but they have a valid expansion to Rust tokens and are thus called "active". -//! I personally like calling these *active* compiler-provided attributes, built-in *macros*, -//! because they still expand, and this helps to differentiate them from built-in *attributes*. -//! However, I'll be the first to admit that the naming here can be confusing. +//! ## Background +//! Previously, the compiler had a single attribute definition (`ast::Attribute`) with parsing and +//! validation scattered throughout the codebase. This was reorganized for better maintainability +//! (see [#131229](https://github.com/rust-lang/rust/issues/131229)). //! -//! The alternative to active attributes, are inert attributes. -//! These can occur in user code (proc-macro helper attributes). -//! But what's important is, many built-in attributes are inert like this. -//! There is nothing they expand to during the macro expansion process, -//! sometimes because they literally cannot expand to something that is valid Rust. -//! They are really just markers to guide the compilation process. -//! An example is `#[inline(...)]` which changes how code for functions is generated. +//! ## Types of Attributes +//! In Rust, attributes are markers that can be attached to items. They come in two main categories. +//! +//! ### 1. Active Attributes +//! These are attribute-like proc-macros that expand into other Rust code. +//! They can be either user-defined or compiler-provided. Examples of compiler-provided active attributes: +//! - `#[derive(...)]`: Expands into trait implementations +//! - `#[cfg()]`: Expands based on configuration +//! - `#[cfg_attr()]`: Conditional attribute application +//! +//! ### 2. Inert Attributes +//! These are pure markers that don't expand into other code. They guide the compilation process. +//! They can be user-defined (in proc-macro helpers) or built-in. Examples of built-in inert attributes: +//! - `#[stable()]`: Marks stable API items +//! - `#[inline()]`: Suggests function inlining +//! - `#[repr()]`: Controls type representation //! //! ```text //! Active Inert @@ -33,27 +40,21 @@ //! │ (mostly in) │ these are parsed │ //! │ rustc_builtin_macros │ here! │ //! │ │ │ -//! │ │ │ //! │ #[derive(...)] │ #[stable()] │ //! Built-in │ #[cfg()] │ #[inline()] │ //! │ #[cfg_attr()] │ #[repr()] │ //! │ │ │ -//! │ │ │ -//! │ │ │ //! ├──────────────────────┼──────────────────────┤ //! │ │ │ -//! │ │ │ //! │ │ `b` in │ //! │ │ #[proc_macro_derive( │ //! User created │ #[proc_macro_attr()] │ a, │ //! │ │ attributes(b) │ //! │ │ ] │ -//! │ │ │ -//! │ │ │ -//! │ │ │ //! └──────────────────────┴──────────────────────┘ //! ``` //! +//! ## How This Crate Works //! In this crate, syntactical attributes (sequences of tokens that look like //! `#[something(something else)]`) are parsed into more semantic attributes, markers on items. //! Multiple syntactic attributes might influence a single semantic attribute. For example, @@ -63,18 +64,17 @@ //! and `#[unstable()]` syntactic attributes, and at the end produce a single //! [`AttributeKind::Stability`](rustc_attr_data_structures::AttributeKind::Stability). //! -//! As a rule of thumb, when a syntactical attribute can be applied more than once, they should be -//! combined into a single semantic attribute. For example: +//! When multiple instances of the same attribute are allowed, they're combined into a single +//! semantic attribute. For example: //! -//! ``` +//! ```rust //! #[repr(C)] //! #[repr(packed)] //! struct Meow {} //! ``` //! -//! should result in a single `AttributeKind::Repr` containing a list of repr annotations, in this -//! case `C` and `packed`. This is equivalent to writing `#[repr(C, packed)]` in a single -//! syntactical annotation. +//! This is equivalent to `#[repr(C, packed)]` and results in a single `AttributeKind::Repr` +//! containing both `C` and `packed` annotations. // tidy-alphabetical-start #![allow(internal_features)] diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index b7b6a2da549..1b4bb11d87b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -263,7 +263,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // something that already has `Fn`-like bounds (or is a closure), so we can't // restrict anyways. } else { - let copy_did = self.infcx.tcx.require_lang_item(LangItem::Copy, Some(span)); + let copy_did = self.infcx.tcx.require_lang_item(LangItem::Copy, span); self.suggest_adding_bounds(&mut err, ty, copy_did, span); } @@ -1915,7 +1915,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let local_ty = self.body.local_decls[place.local].ty; let typeck_results = tcx.typeck(self.mir_def_id()); - let clone = tcx.require_lang_item(LangItem::Clone, Some(body.span)); + let clone = tcx.require_lang_item(LangItem::Clone, body.span); for expr in expr_finder.clones { if let hir::ExprKind::MethodCall(_, rcvr, _, span) = expr.kind && let Some(rcvr_ty) = typeck_results.node_type_opt(rcvr.hir_id) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 4f5baeff7c3..4f75dd7e992 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -688,7 +688,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { if !self.unsized_feature_enabled() { let trait_ref = ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), + tcx.require_lang_item(LangItem::Sized, self.last_span), [place_ty], ); self.prove_trait_ref( @@ -1010,7 +1010,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let ty = place.ty(self.body, tcx).ty; let trait_ref = ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Copy, Some(span)), + tcx.require_lang_item(LangItem::Copy, span), [ty], ); @@ -1025,11 +1025,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => { - let trait_ref = ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::Sized, Some(span)), - [ty], - ); + let trait_ref = + ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, span), [ty]); self.prove_trait_ref( trait_ref, @@ -1041,11 +1038,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { &Rvalue::NullaryOp(NullOp::UbChecks, _) => {} Rvalue::ShallowInitBox(_operand, ty) => { - let trait_ref = ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::Sized, Some(span)), - [*ty], - ); + let trait_ref = + ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, span), [*ty]); self.prove_trait_ref( trait_ref, @@ -1222,7 +1216,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let &ty = ty; let trait_ref = ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)), + tcx.require_lang_item(LangItem::CoerceUnsized, span), [op.ty(self.body, tcx), ty], ); @@ -1811,7 +1805,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { let trait_ref = ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Copy, Some(self.last_span)), + tcx.require_lang_item(LangItem::Copy, self.last_span), [place_ty.ty], ); diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index c11e14d214c..846299711be 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -544,10 +544,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { // (as it's created inside the body itself, not passed in from outside). if let DefiningTy::FnDef(def_id, _) = defining_ty { if self.infcx.tcx.fn_sig(def_id).skip_binder().c_variadic() { - let va_list_did = self.infcx.tcx.require_lang_item( - LangItem::VaList, - Some(self.infcx.tcx.def_span(self.mir_def)), - ); + let va_list_did = self + .infcx + .tcx + .require_lang_item(LangItem::VaList, self.infcx.tcx.def_span(self.mir_def)); let reg_vid = self .infcx diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 4617304105a..0b641ba64b7 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -380,7 +380,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { rustc_hir::LangItem::PanicBoundsCheck, &[index, len, location], *unwind, - Some(source_info.span), + source_info.span, ); } AssertKind::MisalignedPointerDereference { ref required, ref found } => { @@ -393,7 +393,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { rustc_hir::LangItem::PanicMisalignedPointerDereference, &[required, found, location], *unwind, - Some(source_info.span), + source_info.span, ); } AssertKind::NullPointerDereference => { @@ -404,7 +404,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { rustc_hir::LangItem::PanicNullPointerDereference, &[location], *unwind, - Some(source_info.span), + source_info.span, ) } _ => { @@ -415,7 +415,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { msg.panic_function(), &[location], *unwind, - Some(source_info.span), + source_info.span, ); } } @@ -531,7 +531,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { ); } TerminatorKind::UnwindTerminate(reason) => { - codegen_unwind_terminate(fx, Some(source_info.span), *reason); + codegen_unwind_terminate(fx, source_info.span, *reason); } TerminatorKind::UnwindResume => { // FIXME implement unwinding @@ -1074,7 +1074,7 @@ pub(crate) fn codegen_operand<'tcx>( pub(crate) fn codegen_panic_nounwind<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, msg_str: &str, - span: Option<Span>, + span: Span, ) { let msg_ptr = fx.anonymous_str(msg_str); let msg_len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap()); @@ -1091,7 +1091,7 @@ pub(crate) fn codegen_panic_nounwind<'tcx>( pub(crate) fn codegen_unwind_terminate<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, - span: Option<Span>, + span: Span, reason: UnwindTerminateReason, ) { codegen_panic_inner(fx, reason.lang_item(), &[], UnwindAction::Unreachable, span); @@ -1102,7 +1102,7 @@ fn codegen_panic_inner<'tcx>( lang_item: rustc_hir::LangItem, args: &[Value], _unwind: UnwindAction, - span: Option<Span>, + span: Span, ) { fx.bcx.set_cold_block(fx.bcx.current_block().unwrap()); diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs index 2e02e85a997..99a5518d0b6 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs @@ -71,7 +71,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( See https://github.com/rust-lang/rustc_codegen_cranelift/issues/171\n\ Please open an issue at https://github.com/rust-lang/rustc_codegen_cranelift/issues" ); - crate::base::codegen_panic_nounwind(fx, &msg, None); + crate::base::codegen_panic_nounwind(fx, &msg, span); return; } } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs index d22483cf177..c22f2a7b873 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs @@ -512,7 +512,7 @@ pub(super) fn codegen_aarch64_llvm_intrinsic_call<'tcx>( See https://github.com/rust-lang/rustc_codegen_cranelift/issues/171\n\ Please open an issue at https://github.com/rust-lang/rustc_codegen_cranelift/issues" ); - crate::base::codegen_panic_nounwind(fx, &msg, None); + crate::base::codegen_panic_nounwind(fx, &msg, fx.mir.span); return; } } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs index 3d67913a8ff..615f6c47d90 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs @@ -1321,7 +1321,7 @@ pub(super) fn codegen_x86_llvm_intrinsic_call<'tcx>( See https://github.com/rust-lang/rustc_codegen_cranelift/issues/171\n\ Please open an issue at https://github.com/rust-lang/rustc_codegen_cranelift/issues" ); - crate::base::codegen_panic_nounwind(fx, &msg, None); + crate::base::codegen_panic_nounwind(fx, &msg, span); return; } } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 0de23e55e81..27a5df8b152 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -785,7 +785,7 @@ fn codegen_regular_intrinsic_call<'tcx>( } }) }); - crate::base::codegen_panic_nounwind(fx, &msg_str, Some(source_info.span)); + crate::base::codegen_panic_nounwind(fx, &msg_str, source_info.span); return Ok(()); } } @@ -884,7 +884,7 @@ fn codegen_regular_intrinsic_call<'tcx>( crate::base::codegen_panic_nounwind( fx, "128bit atomics not yet supported", - None, + source_info.span, ); return Ok(()); } else { @@ -919,7 +919,7 @@ fn codegen_regular_intrinsic_call<'tcx>( crate::base::codegen_panic_nounwind( fx, "128bit atomics not yet supported", - None, + source_info.span, ); return Ok(()); } else { diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs index 6eef97c14dd..bf756860b64 100644 --- a/compiler/rustc_codegen_cranelift/src/main_shim.rs +++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs @@ -101,7 +101,7 @@ pub(crate) fn maybe_create_entry_wrapper( let call_inst = bcx.ins().call(main_func_ref, &[]); let call_results = bcx.func.dfg.inst_results(call_inst).to_owned(); - let termination_trait = tcx.require_lang_item(LangItem::Termination, None); + let termination_trait = tcx.require_lang_item(LangItem::Termination, DUMMY_SP); let report = tcx .associated_items(termination_trait) .find_by_ident_and_kind( @@ -136,7 +136,7 @@ pub(crate) fn maybe_create_entry_wrapper( } } else { // Regular main fn invoked via start lang item. - let start_def_id = tcx.require_lang_item(LangItem::Start, None); + let start_def_id = tcx.require_lang_item(LangItem::Start, DUMMY_SP); let start_instance = Instance::expect_resolve( tcx, ty::TypingEnv::fully_monomorphized(), diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs index f53045df6e7..95d44dfb6d9 100644 --- a/compiler/rustc_codegen_cranelift/src/num.rs +++ b/compiler/rustc_codegen_cranelift/src/num.rs @@ -54,7 +54,7 @@ fn codegen_three_way_compare<'tcx>( let gt = fx.bcx.ins().icmp(gt_cc, lhs, rhs); let lt = fx.bcx.ins().icmp(lt_cc, lhs, rhs); let val = fx.bcx.ins().isub(gt, lt); - CValue::by_val(val, fx.layout_of(fx.tcx.ty_ordering_enum(Some(fx.mir.span)))) + CValue::by_val(val, fx.layout_of(fx.tcx.ty_ordering_enum(fx.mir.span))) } fn codegen_compare_bin_op<'tcx>( diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs index f8bbb214920..662546e4999 100644 --- a/compiler/rustc_codegen_cranelift/src/unsize.rs +++ b/compiler/rustc_codegen_cranelift/src/unsize.rs @@ -240,7 +240,7 @@ pub(crate) fn size_and_align_of<'tcx>( }) }); - codegen_panic_nounwind(fx, &msg_str, None); + codegen_panic_nounwind(fx, &msg_str, fx.mir.span); fx.bcx.switch_to_block(next_block); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index f7863fe4ae2..c2d6a26de0f 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -561,7 +561,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let EntryFnType::Main { sigpipe } = entry_type; let (start_fn, start_ty, args, instance) = { - let start_def_id = cx.tcx().require_lang_item(LangItem::Start, None); + let start_def_id = cx.tcx().require_lang_item(LangItem::Start, DUMMY_SP); let start_instance = ty::Instance::expect_resolve( cx.tcx(), cx.typing_env(), diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index ef0d565333e..48565e0b4de 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -110,7 +110,7 @@ mod temp_stable_hash_impls { pub(crate) fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &Bx, - span: Option<Span>, + span: Span, li: LangItem, ) -> (Bx::FnAbiOfResult, Bx::Value, Instance<'tcx>) { let tcx = bx.tcx(); diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 1baab62ae43..bfc367f7a4d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -783,7 +783,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } }; - let (fn_abi, llfn, instance) = common::build_langcall(bx, Some(span), lang_item); + let (fn_abi, llfn, instance) = common::build_langcall(bx, span, lang_item); // Codegen the actual panic invoke/call. let merging_succ = @@ -803,7 +803,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.set_debug_loc(bx, terminator.source_info); // Obtain the panic entry point. - let (fn_abi, llfn, instance) = common::build_langcall(bx, Some(span), reason.lang_item()); + let (fn_abi, llfn, instance) = common::build_langcall(bx, span, reason.lang_item()); // Codegen the actual panic invoke/call. let merging_succ = helper.do_call( @@ -871,7 +871,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Obtain the panic entry point. let (fn_abi, llfn, instance) = - common::build_langcall(bx, Some(source_info.span), LangItem::PanicNounwind); + common::build_langcall(bx, source_info.span, LangItem::PanicNounwind); // Codegen the actual panic invoke/call. Some(helper.do_call( @@ -1830,7 +1830,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.set_debug_loc(&mut bx, mir::SourceInfo::outermost(self.mir.span)); - let (fn_abi, fn_ptr, instance) = common::build_langcall(&bx, None, reason.lang_item()); + let (fn_abi, fn_ptr, instance) = + common::build_langcall(&bx, self.mir.span, reason.lang_item()); if is_call_from_compiler_builtins_to_upstream_monomorphization(bx.tcx(), instance) { bx.abort(); } else { diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index b7f2277bfda..e9389ddf93b 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -45,9 +45,15 @@ pub enum OperandValue<V> { Immediate(V), /// A pair of immediate LLVM values. Used by wide pointers too. /// - /// An `OperandValue` *must* be this variant for any type for which + /// # Invariants + /// - For `Pair(a, b)`, `a` is always at offset 0, but may have `FieldIdx(1..)` + /// - `b` is not at offset 0, because `V` is not a 1ZST type. + /// - `a` and `b` will have a different FieldIdx, but otherwise `b`'s may be lower + /// or they may not be adjacent, due to arbitrary numbers of 1ZST fields that + /// will not affect the shape of the data which determines if `Pair` will be used. + /// - An `OperandValue` *must* be this variant for any type for which /// [`LayoutTypeCodegenMethods::is_backend_scalar_pair`] returns `true`. - /// The backend values in this variant must be the *immediate* backend types, + /// - The backend values in this variant must be the *immediate* backend types, /// as returned by [`LayoutTypeCodegenMethods::scalar_pair_element_backend_type`] /// with `immediate: true`. Pair(V, V), diff --git a/compiler/rustc_codegen_ssa/src/size_of_val.rs b/compiler/rustc_codegen_ssa/src/size_of_val.rs index ac2366340fb..577012151e4 100644 --- a/compiler/rustc_codegen_ssa/src/size_of_val.rs +++ b/compiler/rustc_codegen_ssa/src/size_of_val.rs @@ -5,6 +5,7 @@ use rustc_hir::LangItem; use rustc_middle::bug; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::{self, Ty}; +use rustc_span::DUMMY_SP; use tracing::{debug, trace}; use crate::common::IntPredicate; @@ -62,7 +63,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // Obtain the panic entry point. let (fn_abi, llfn, _instance) = - common::build_langcall(bx, None, LangItem::PanicNounwind); + common::build_langcall(bx, DUMMY_SP, LangItem::PanicNounwind); // Generate the call. Cannot use `do_call` since we don't have a MIR terminator so we // can't create a `TerminationCodegenHelper`. (But we are in good company, this code is diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index d701646719a..9c30dbff99e 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -345,11 +345,7 @@ fn build_error_for_const_call<'tcx>( non_or_conditionally, }); - note_trait_if_possible( - &mut err, - self_ty, - tcx.require_lang_item(LangItem::Deref, Some(span)), - ); + note_trait_if_possible(&mut err, self_ty, tcx.require_lang_item(LangItem::Deref, span)); err } _ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::FmtArgumentsNew) => { diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index dfcd1969a73..c1a37ab6a83 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -99,7 +99,7 @@ impl Qualif for HasMutInterior { // requires borrowck, which in turn will invoke mir_const_qualifs again, causing a cycle error. // Instead we invoke an obligation context manually, and provide the opaque type inference settings // that allow the trait solver to just error out instead of cycling. - let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, Some(cx.body.span)); + let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, cx.body.span); // FIXME(#132279): Once we've got a typing mode which reveals opaque types using the HIR // typeck results without causing query cycles, we should use this here instead of defining // opaque types. @@ -180,7 +180,7 @@ impl Qualif for NeedsNonConstDrop { // that the components of this type are also `~const Destruct`. This // amounts to verifying that there are no values in this ADT that may have // a non-const drop. - let destruct_def_id = cx.tcx.require_lang_item(LangItem::Destruct, Some(cx.body.span)); + let destruct_def_id = cx.tcx.require_lang_item(LangItem::Destruct, cx.body.span); let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env); let ocx = ObligationCtxt::new(&infcx); ocx.register_obligation(Obligation::new( diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 01625b91353..2556e57a58f 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -454,11 +454,12 @@ fn report_eval_error<'tcx>( // FIXME(oli-obk): figure out how to use structured diagnostics again. diag.code(E0080); diag.span_label(span, crate::fluent_generated::const_eval_error); - diag.arg("instance", instance); - diag.arg("error_kind", kind); for frame in frames { diag.subdiagnostic(frame); } + // Add after the frame rendering above, as it adds its own `instance` args. + diag.arg("instance", instance); + diag.arg("error_kind", kind); }, ) } diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 3922b33ea84..a68dcf29988 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -249,7 +249,7 @@ impl<'tcx> CompileTimeInterpCx<'tcx> { return Err(ConstEvalErrKind::Panic { msg, file, line, col }).into(); } else if self.tcx.is_lang_item(def_id, LangItem::PanicFmt) { // For panic_fmt, call const_panic_fmt instead. - let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, None); + let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, self.tcx.span); let new_instance = ty::Instance::expect_resolve( *self.tcx, self.typing_env(), diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 39755169e6c..77667ba823a 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -12,6 +12,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter}; use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt}; use rustc_middle::{bug, mir, span_bug, ty}; +use rustc_span::DUMMY_SP; use tracing::trace; use super::{ @@ -307,7 +308,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { #[inline] pub fn from_ordering(c: std::cmp::Ordering, tcx: TyCtxt<'tcx>) -> Self { // Can use any typing env, since `Ordering` is always monomorphic. - let ty = tcx.ty_ordering_enum(None); + let ty = tcx.ty_ordering_enum(DUMMY_SP); let layout = tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)).unwrap(); Self::from_scalar(Scalar::Int(c.into()), layout) diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index 9c867cc615e..39f7e0dbadd 100644 --- a/compiler/rustc_const_eval/src/util/caller_location.rs +++ b/compiler/rustc_const_eval/src/util/caller_location.rs @@ -35,7 +35,7 @@ fn alloc_caller_location<'tcx>( // Allocate memory for `CallerLocation` struct. let loc_ty = ecx .tcx - .type_of(ecx.tcx.require_lang_item(LangItem::PanicLocation, None)) + .type_of(ecx.tcx.require_lang_item(LangItem::PanicLocation, ecx.tcx.span)) .instantiate(*ecx.tcx, ecx.tcx.mk_args(&[ecx.tcx.lifetimes.re_erased.into()])); let loc_layout = ecx.layout_of(loc_ty).unwrap(); let location = ecx.allocate(loc_layout, MemoryKind::CallerLocation).unwrap(); diff --git a/compiler/rustc_error_codes/src/error_codes/E0783.md b/compiler/rustc_error_codes/src/error_codes/E0783.md index 73981e59e0d..ac8641cfc5a 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0783.md +++ b/compiler/rustc_error_codes/src/error_codes/E0783.md @@ -9,7 +9,7 @@ match 2u8 { } ``` -Older Rust code using previous editions allowed `...` to stand for exclusive +Older Rust code using previous editions allowed `...` to stand for inclusive ranges which are now signified using `..=`. To make this code compile replace the `...` with `..=`. diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 98ec1ccd6ba..459fe5935e0 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -852,12 +852,7 @@ pub enum LifetimeRes { /// late resolution. Those lifetimes will be inferred by typechecking. Infer, /// `'static` lifetime. - Static { - /// We do not want to emit `elided_named_lifetimes` - /// when we are inside of a const item or a static, - /// because it would get too annoying. - suppress_elision_warning: bool, - }, + Static, /// Resolution failure. Error, /// HACK: This is used to recover the NodeId of an elided lifetime. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 433d5f98829..6f288bb39b9 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -72,13 +72,13 @@ pub enum LifetimeSource { #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)] pub enum LifetimeSyntax { /// E.g. `&Type`, `ContainsLifetime` - Hidden, + Implicit, /// E.g. `&'_ Type`, `ContainsLifetime<'_>`, `impl Trait + '_`, `impl Trait + use<'_>` - Anonymous, + ExplicitAnonymous, /// E.g. `&'a Type`, `ContainsLifetime<'a>`, `impl Trait + 'a`, `impl Trait + use<'a>` - Named, + ExplicitBound, } impl From<Ident> for LifetimeSyntax { @@ -88,10 +88,10 @@ impl From<Ident> for LifetimeSyntax { if name == sym::empty { unreachable!("A lifetime name should never be empty"); } else if name == kw::UnderscoreLifetime { - LifetimeSyntax::Anonymous + LifetimeSyntax::ExplicitAnonymous } else { debug_assert!(name.as_str().starts_with('\'')); - LifetimeSyntax::Named + LifetimeSyntax::ExplicitBound } } } @@ -102,48 +102,48 @@ impl From<Ident> for LifetimeSyntax { /// /// ``` /// #[repr(C)] -/// struct S<'a>(&'a u32); // res=Param, name='a, source=Reference, syntax=Named +/// struct S<'a>(&'a u32); // res=Param, name='a, source=Reference, syntax=ExplicitBound /// unsafe extern "C" { -/// fn f1(s: S); // res=Param, name='_, source=Path, syntax=Hidden -/// fn f2(s: S<'_>); // res=Param, name='_, source=Path, syntax=Anonymous -/// fn f3<'a>(s: S<'a>); // res=Param, name='a, source=Path, syntax=Named +/// fn f1(s: S); // res=Param, name='_, source=Path, syntax=Implicit +/// fn f2(s: S<'_>); // res=Param, name='_, source=Path, syntax=ExplicitAnonymous +/// fn f3<'a>(s: S<'a>); // res=Param, name='a, source=Path, syntax=ExplicitBound /// } /// -/// struct St<'a> { x: &'a u32 } // res=Param, name='a, source=Reference, syntax=Named +/// struct St<'a> { x: &'a u32 } // res=Param, name='a, source=Reference, syntax=ExplicitBound /// fn f() { -/// _ = St { x: &0 }; // res=Infer, name='_, source=Path, syntax=Hidden -/// _ = St::<'_> { x: &0 }; // res=Infer, name='_, source=Path, syntax=Anonymous +/// _ = St { x: &0 }; // res=Infer, name='_, source=Path, syntax=Implicit +/// _ = St::<'_> { x: &0 }; // res=Infer, name='_, source=Path, syntax=ExplicitAnonymous /// } /// -/// struct Name<'a>(&'a str); // res=Param, name='a, source=Reference, syntax=Named -/// const A: Name = Name("a"); // res=Static, name='_, source=Path, syntax=Hidden -/// const B: &str = ""; // res=Static, name='_, source=Reference, syntax=Hidden -/// static C: &'_ str = ""; // res=Static, name='_, source=Reference, syntax=Anonymous -/// static D: &'static str = ""; // res=Static, name='static, source=Reference, syntax=Named +/// struct Name<'a>(&'a str); // res=Param, name='a, source=Reference, syntax=ExplicitBound +/// const A: Name = Name("a"); // res=Static, name='_, source=Path, syntax=Implicit +/// const B: &str = ""; // res=Static, name='_, source=Reference, syntax=Implicit +/// static C: &'_ str = ""; // res=Static, name='_, source=Reference, syntax=ExplicitAnonymous +/// static D: &'static str = ""; // res=Static, name='static, source=Reference, syntax=ExplicitBound /// /// trait Tr {} -/// fn tr(_: Box<dyn Tr>) {} // res=ImplicitObjectLifetimeDefault, name='_, source=Other, syntax=Hidden +/// fn tr(_: Box<dyn Tr>) {} // res=ImplicitObjectLifetimeDefault, name='_, source=Other, syntax=Implicit /// /// fn capture_outlives<'a>() -> -/// impl FnOnce() + 'a // res=Param, ident='a, source=OutlivesBound, syntax=Named +/// impl FnOnce() + 'a // res=Param, ident='a, source=OutlivesBound, syntax=ExplicitBound /// { /// || {} /// } /// /// fn capture_precise<'a>() -> -/// impl FnOnce() + use<'a> // res=Param, ident='a, source=PreciseCapturing, syntax=Named +/// impl FnOnce() + use<'a> // res=Param, ident='a, source=PreciseCapturing, syntax=ExplicitBound /// { /// || {} /// } /// /// // (commented out because these cases trigger errors) -/// // struct S1<'a>(&'a str); // res=Param, name='a, source=Reference, syntax=Named -/// // struct S2(S1); // res=Error, name='_, source=Path, syntax=Hidden -/// // struct S3(S1<'_>); // res=Error, name='_, source=Path, syntax=Anonymous -/// // struct S4(S1<'a>); // res=Error, name='a, source=Path, syntax=Named +/// // struct S1<'a>(&'a str); // res=Param, name='a, source=Reference, syntax=ExplicitBound +/// // struct S2(S1); // res=Error, name='_, source=Path, syntax=Implicit +/// // struct S3(S1<'_>); // res=Error, name='_, source=Path, syntax=ExplicitAnonymous +/// // struct S4(S1<'a>); // res=Error, name='a, source=Path, syntax=ExplicitBound /// ``` /// -/// Some combinations that cannot occur are `LifetimeSyntax::Hidden` with +/// Some combinations that cannot occur are `LifetimeSyntax::Implicit` with /// `LifetimeSource::OutlivesBound` or `LifetimeSource::PreciseCapturing` /// — there's no way to "elide" these lifetimes. #[derive(Debug, Copy, Clone, HashStable_Generic)] @@ -206,7 +206,7 @@ impl ParamName { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)] pub enum LifetimeKind { /// User-given names or fresh (synthetic) names. Param(LocalDefId), @@ -287,12 +287,8 @@ impl Lifetime { self.ident.name == kw::UnderscoreLifetime } - pub fn is_syntactically_hidden(&self) -> bool { - matches!(self.syntax, LifetimeSyntax::Hidden) - } - - pub fn is_syntactically_anonymous(&self) -> bool { - matches!(self.syntax, LifetimeSyntax::Anonymous) + pub fn is_implicit(&self) -> bool { + matches!(self.syntax, LifetimeSyntax::Implicit) } pub fn is_static(&self) -> bool { @@ -307,28 +303,28 @@ impl Lifetime { match (self.syntax, self.source) { // The user wrote `'a` or `'_`. - (Named | Anonymous, _) => (self.ident.span, format!("{new_lifetime}")), + (ExplicitBound | ExplicitAnonymous, _) => (self.ident.span, format!("{new_lifetime}")), // The user wrote `Path<T>`, and omitted the `'_,`. - (Hidden, Path { angle_brackets: AngleBrackets::Full }) => { + (Implicit, Path { angle_brackets: AngleBrackets::Full }) => { (self.ident.span, format!("{new_lifetime}, ")) } // The user wrote `Path<>`, and omitted the `'_`.. - (Hidden, Path { angle_brackets: AngleBrackets::Empty }) => { + (Implicit, Path { angle_brackets: AngleBrackets::Empty }) => { (self.ident.span, format!("{new_lifetime}")) } // The user wrote `Path` and omitted the `<'_>`. - (Hidden, Path { angle_brackets: AngleBrackets::Missing }) => { + (Implicit, Path { angle_brackets: AngleBrackets::Missing }) => { (self.ident.span.shrink_to_hi(), format!("<{new_lifetime}>")) } // The user wrote `&type` or `&mut type`. - (Hidden, Reference) => (self.ident.span, format!("{new_lifetime} ")), + (Implicit, Reference) => (self.ident.span, format!("{new_lifetime} ")), - (Hidden, source) => { - unreachable!("can't suggest for a hidden lifetime of {source:?}") + (Implicit, source) => { + unreachable!("can't suggest for a implicit lifetime of {source:?}") } } } diff --git a/compiler/rustc_hir/src/hir/tests.rs b/compiler/rustc_hir/src/hir/tests.rs index 8684adee29c..1fd793bc161 100644 --- a/compiler/rustc_hir/src/hir/tests.rs +++ b/compiler/rustc_hir/src/hir/tests.rs @@ -55,7 +55,7 @@ fn trait_object_roundtrips_impl(syntax: TraitObjectSyntax) { ident: Ident::new(sym::name, DUMMY_SP), kind: LifetimeKind::Static, source: LifetimeSource::Other, - syntax: LifetimeSyntax::Hidden, + syntax: LifetimeSyntax::Implicit, }; let unambig = TyKind::TraitObject::<'_, ()>(&[], TaggedRef::new(<, syntax)); let unambig_to_ambig = unsafe { std::mem::transmute::<_, TyKind<'_, AmbigArg>>(unambig) }; diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 846eacce9e1..77f6204d595 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -97,7 +97,7 @@ fn allowed_union_or_unsafe_field<'tcx>( let def_id = tcx .lang_items() .get(LangItem::BikeshedGuaranteedNoDrop) - .unwrap_or_else(|| tcx.require_lang_item(LangItem::Copy, Some(span))); + .unwrap_or_else(|| tcx.require_lang_item(LangItem::Copy, span)); let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, ty) else { tcx.dcx().span_delayed_bug(span, "could not normalize field type"); return true; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 09610a2f3ec..234520c1583 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -180,7 +180,7 @@ pub(crate) fn check_intrinsic_type( ty::BoundVariableKind::Region(ty::BoundRegionKind::ClosureEnv), ]); let mk_va_list_ty = |mutbl| { - let did = tcx.require_lang_item(LangItem::VaList, Some(span)); + let did = tcx.require_lang_item(LangItem::VaList, span); let region = ty::Region::new_bound( tcx, ty::INNERMOST, @@ -442,9 +442,7 @@ pub(crate) fn check_intrinsic_type( sym::bswap | sym::bitreverse => (1, 0, vec![param(0)], param(0)), - sym::three_way_compare => { - (1, 0, vec![param(0), param(0)], tcx.ty_ordering_enum(Some(span))) - } + sym::three_way_compare => (1, 0, vec![param(0), param(0)], tcx.ty_ordering_enum(span)), sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => { (1, 0, vec![param(0), param(0)], Ty::new_tup(tcx, &[param(0), tcx.types.bool])) @@ -520,7 +518,7 @@ pub(crate) fn check_intrinsic_type( sym::discriminant_value => { let assoc_items = tcx.associated_item_def_ids( - tcx.require_lang_item(hir::LangItem::DiscriminantKind, None), + tcx.require_lang_item(hir::LangItem::DiscriminantKind, span), ); let discriminant_def_id = assoc_items[0]; diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 3e872607e31..237b8ae8b89 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -969,7 +969,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), ), wfcx.param_env, ty, - tcx.require_lang_item(LangItem::UnsizedConstParamTy, Some(hir_ty.span)), + tcx.require_lang_item(LangItem::UnsizedConstParamTy, hir_ty.span), ); Ok(()) }) @@ -983,7 +983,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), ), wfcx.param_env, ty, - tcx.require_lang_item(LangItem::ConstParamTy, Some(hir_ty.span)), + tcx.require_lang_item(LangItem::ConstParamTy, hir_ty.span), ); Ok(()) }) @@ -1232,7 +1232,7 @@ fn check_type_defn<'tcx>( ), wfcx.param_env, ty, - tcx.require_lang_item(LangItem::Sized, Some(hir_ty.span)), + tcx.require_lang_item(LangItem::Sized, hir_ty.span), ); } @@ -1356,7 +1356,7 @@ fn check_static_item( ), wfcx.param_env, item_ty, - tcx.require_lang_item(LangItem::Sized, Some(ty_span)), + tcx.require_lang_item(LangItem::Sized, ty_span), ); } @@ -1375,7 +1375,7 @@ fn check_static_item( ), wfcx.param_env, item_ty, - tcx.require_lang_item(LangItem::Sync, Some(ty_span)), + tcx.require_lang_item(LangItem::Sync, ty_span), ); } Ok(()) @@ -1401,7 +1401,7 @@ fn check_const_item( ), wfcx.param_env, ty, - tcx.require_lang_item(LangItem::Sized, None), + tcx.require_lang_item(LangItem::Sized, ty_span), ); check_where_clauses(wfcx, item_span, def_id); @@ -1725,13 +1725,13 @@ fn check_fn_or_method<'tcx>( ObligationCause::new(span, wfcx.body_def_id, ObligationCauseCode::RustCall), wfcx.param_env, *ty, - tcx.require_lang_item(hir::LangItem::Tuple, Some(span)), + tcx.require_lang_item(hir::LangItem::Tuple, span), ); wfcx.register_bound( ObligationCause::new(span, wfcx.body_def_id, ObligationCauseCode::RustCall), wfcx.param_env, *ty, - tcx.require_lang_item(hir::LangItem::Sized, Some(span)), + tcx.require_lang_item(hir::LangItem::Sized, span), ); } else { tcx.dcx().span_err( @@ -1776,7 +1776,7 @@ fn check_sized_if_body<'tcx>( ObligationCause::new(span, def_id, code), wfcx.param_env, ty, - tcx.require_lang_item(LangItem::Sized, Some(span)), + tcx.require_lang_item(LangItem::Sized, span), ); } } @@ -2013,7 +2013,7 @@ fn receiver_is_valid<'tcx>( // deref chain implement `LegacyReceiver`. if arbitrary_self_types_enabled.is_none() { let legacy_receiver_trait_def_id = - tcx.require_lang_item(LangItem::LegacyReceiver, Some(span)); + tcx.require_lang_item(LangItem::LegacyReceiver, span); if !legacy_receiver_is_implemented( wfcx, legacy_receiver_trait_def_id, diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index b92d1d7104f..4779f4fb702 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -225,7 +225,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() // redundant errors for `DispatchFromDyn`. This is best effort, though. let mut res = Ok(()); tcx.for_each_relevant_impl( - tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)), + tcx.require_lang_item(LangItem::CoerceUnsized, span), source, |impl_def_id| { res = res.and(tcx.ensure_ok().coerce_unsized_info(impl_def_id)); @@ -379,8 +379,8 @@ pub(crate) fn coerce_unsized_info<'tcx>( let span = tcx.def_span(impl_did); let trait_name = "CoerceUnsized"; - let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)); - let unsize_trait = tcx.require_lang_item(LangItem::Unsize, Some(span)); + let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, span); + let unsize_trait = tcx.require_lang_item(LangItem::Unsize, span); let source = tcx.type_of(impl_did).instantiate_identity(); let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().instantiate_identity(); @@ -591,7 +591,7 @@ fn infringing_fields_error<'tcx>( impl_did: LocalDefId, impl_span: Span, ) -> ErrorGuaranteed { - let trait_did = tcx.require_lang_item(lang_item, Some(impl_span)); + let trait_did = tcx.require_lang_item(lang_item, impl_span); let trait_name = tcx.def_path_str(trait_did); @@ -748,7 +748,7 @@ fn visit_implementation_of_pointer_like(checker: &Checker<'_>) -> Result<(), Err ObligationCause::misc(impl_span, checker.impl_def_id), param_env, nontrivial_field_ty, - tcx.require_lang_item(LangItem::PointerLike, Some(impl_span)), + tcx.require_lang_item(LangItem::PointerLike, impl_span), ); // FIXME(dyn-star): We should regionck this implementation. if ocx.select_all_or_error().is_empty() { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 2a37a8bdbd4..4c65d0d0510 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2590,7 +2590,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .unwrap_or_else(|guar| Ty::new_error(tcx, guar)) } &hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => { - let def_id = tcx.require_lang_item(lang_item, Some(span)); + let def_id = tcx.require_lang_item(lang_item, span); let (args, _) = self.lower_generic_args_of_path( span, def_id, diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index f555d116c52..d173fe7c2c2 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -508,7 +508,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(ty) = fn_sig.inputs().last().copied() { self.register_bound( ty, - self.tcx.require_lang_item(hir::LangItem::Tuple, Some(sp)), + self.tcx.require_lang_item(hir::LangItem::Tuple, sp), self.cause(sp, ObligationCauseCode::RustCall), ); self.require_type_is_sized(ty, sp, ObligationCauseCode::RustCall); diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 99103f14d68..ac42eebf08c 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -57,7 +57,7 @@ pub(super) fn check_fn<'a, 'tcx>( // (as it's created inside the body itself, not passed in from outside). let maybe_va_list = fn_sig.c_variadic.then(|| { let span = body.params.last().unwrap().span; - let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(span)); + let va_list_did = tcx.require_lang_item(LangItem::VaList, span); let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span)); tcx.type_of(va_list_did).instantiate(tcx, &[region.into()]) @@ -178,7 +178,7 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_> tcx.dcx().span_err(span, "should have no const parameters"); } - let panic_info_did = tcx.require_lang_item(hir::LangItem::PanicInfo, Some(span)); + let panic_info_did = tcx.require_lang_item(hir::LangItem::PanicInfo, span); // build type `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !` let panic_info_ty = tcx.type_of(panic_info_did).instantiate( diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index cd3746be1d1..459c0498d50 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -142,13 +142,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ty::new_adt( tcx, - tcx.adt_def( - tcx.require_lang_item(hir::LangItem::Poll, Some(expr_span)), - ), + tcx.adt_def(tcx.require_lang_item(hir::LangItem::Poll, expr_span)), tcx.mk_args(&[Ty::new_adt( tcx, tcx.adt_def( - tcx.require_lang_item(hir::LangItem::Option, Some(expr_span)), + tcx.require_lang_item(hir::LangItem::Option, expr_span), ), tcx.mk_args(&[yield_ty.into()]), ) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index ddc80fab2ce..d9fa56fefeb 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -760,8 +760,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { self.param_env, ty::TraitRef::new( self.tcx, - self.tcx - .require_lang_item(hir::LangItem::PointerLike, Some(self.cause.span)), + self.tcx.require_lang_item(hir::LangItem::PointerLike, self.cause.span), [a], ), ), @@ -1969,7 +1968,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { fcx.param_env, ty::TraitRef::new( fcx.tcx, - fcx.tcx.require_lang_item(hir::LangItem::Sized, None), + fcx.tcx.require_lang_item(hir::LangItem::Sized, DUMMY_SP), [sig.output()], ), )) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 082ddac7e5a..b17d5977e06 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1407,7 +1407,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let lhs_deref_ty_is_sized = self .infcx .type_implements_trait( - self.tcx.require_lang_item(LangItem::Sized, None), + self.tcx.require_lang_item(LangItem::Sized, span), [lhs_deref_ty], self.param_env, ) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 362c7d8efac..8a90e768d70 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -409,7 +409,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { code: traits::ObligationCauseCode<'tcx>, ) { if !ty.references_error() { - let lang_item = self.tcx.require_lang_item(LangItem::Sized, None); + let lang_item = self.tcx.require_lang_item(LangItem::Sized, span); self.require_type_meets(ty, span, code, lang_item); } } @@ -443,7 +443,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Nothing else is required here. } else { // We can't be sure, let's required full `Sized`. - let lang_item = self.tcx.require_lang_item(LangItem::Sized, None); + let lang_item = self.tcx.require_lang_item(LangItem::Sized, span); self.require_type_meets(ty, span, ObligationCauseCode::Misc, lang_item); } } @@ -732,7 +732,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, hir_id: HirId, ) -> (Res, Ty<'tcx>) { - let def_id = self.tcx.require_lang_item(lang_item, Some(span)); + let def_id = self.tcx.require_lang_item(lang_item, span); let def_kind = self.tcx.def_kind(def_id); let item_ty = if let DefKind::Variant = def_kind { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 59aba6fae5e..95c7f251c88 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -165,7 +165,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => traits::IsConstable::No, }; - let lang_item = self.tcx.require_lang_item(LangItem::Copy, None); + let lang_item = self.tcx.require_lang_item(LangItem::Copy, element.span); let code = traits::ObligationCauseCode::RepeatElementCopy { is_constable, elt_span: element.span, @@ -1680,8 +1680,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ast::LitKind::CStr(_, _) => Ty::new_imm_ref( tcx, tcx.lifetimes.re_static, - tcx.type_of(tcx.require_lang_item(hir::LangItem::CStr, Some(lit.span))) - .skip_binder(), + tcx.type_of(tcx.require_lang_item(hir::LangItem::CStr, lit.span)).skip_binder(), ), ast::LitKind::Err(guar) => Ty::new_error(tcx, guar), } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 1c3bc338d85..66af085cfd4 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2679,7 +2679,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut sugg_sp = sp; if let hir::ExprKind::MethodCall(segment, receiver, args, _) = expr.kind { let clone_trait = - self.tcx.require_lang_item(LangItem::Clone, Some(segment.ident.span)); + self.tcx.require_lang_item(LangItem::Clone, segment.ident.span); if args.is_empty() && self .typeck_results diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 17d48184dd9..432eeae8016 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -796,7 +796,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if *negated { self.register_bound( ty, - self.tcx.require_lang_item(LangItem::Neg, Some(lt.span)), + self.tcx.require_lang_item(LangItem::Neg, lt.span), ObligationCause::dummy_with_span(lt.span), ); } @@ -2553,13 +2553,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx; self.register_bound( source_ty, - tcx.require_lang_item(hir::LangItem::DerefPure, Some(span)), + tcx.require_lang_item(hir::LangItem::DerefPure, span), self.misc(span), ); // The expected type for the deref pat's inner pattern is `<expected as Deref>::Target`. let target_ty = Ty::new_projection( tcx, - tcx.require_lang_item(hir::LangItem::DerefTarget, Some(span)), + tcx.require_lang_item(hir::LangItem::DerefTarget, span), [source_ty], ); let target_ty = self.normalize(span, target_ty); @@ -2580,7 +2580,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for mutably_derefed_ty in derefed_tys { self.register_bound( mutably_derefed_ty, - self.tcx.require_lang_item(hir::LangItem::DerefMut, Some(span)), + self.tcx.require_lang_item(hir::LangItem::DerefMut, span), self.misc(span), ); } diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 4b2e87f5674..5b5253c7e7e 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -1560,7 +1560,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let is_drop_defined_for_ty = |ty: Ty<'tcx>| { - let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span)); + let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, closure_span); self.infcx .type_implements_trait(drop_trait, [ty], self.tcx.param_env(closure_def_id)) .must_apply_modulo_regions() diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index 2374f388250..ece3f9107b0 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -545,11 +545,12 @@ impl Cursor<'_> { let mut s = self.as_str(); let mut found = false; + let mut size = 0; while let Some(closing) = s.find(&"-".repeat(length_opening as usize)) { let preceding_chars_start = s[..closing].rfind("\n").map_or(0, |i| i + 1); if s[preceding_chars_start..closing].chars().all(is_whitespace) { // candidate found - self.bump_bytes(closing); + self.bump_bytes(size + closing); // in case like // ---cargo // --- blahblah @@ -562,6 +563,7 @@ impl Cursor<'_> { break; } else { s = &s[closing + length_opening as usize..]; + size += closing + length_opening as usize; } } diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index e7e60e8701a..fd2e2ba39ac 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -253,11 +253,6 @@ lint_duplicate_macro_attribute = lint_duplicate_matcher_binding = duplicate matcher binding -lint_elided_named_lifetime = elided lifetime has a name - .label_elided = this elided lifetime gets resolved as `{$name}` - .label_named = lifetime `{$name}` declared here - .suggestion = consider specifying it explicitly - lint_enum_intrinsics_mem_discriminant = the return value of `mem::discriminant` is unspecified when called with a non-enum type .note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum @@ -516,6 +511,28 @@ lint_metavariable_still_repeating = variable `{$name}` is still repeating at thi lint_metavariable_wrong_operator = meta-variable repeats with different Kleene operator +lint_mismatched_lifetime_syntaxes = + lifetime flowing from input to output with different syntax can be confusing + .label_mismatched_lifetime_syntaxes_inputs = + {$n_inputs -> + [one] this lifetime flows + *[other] these lifetimes flow + } to the output + .label_mismatched_lifetime_syntaxes_outputs = + the {$n_outputs -> + [one] lifetime gets + *[other] lifetimes get + } resolved as `{$lifetime_name}` + +lint_mismatched_lifetime_syntaxes_suggestion_explicit = + one option is to consistently use `{$lifetime_name}` + +lint_mismatched_lifetime_syntaxes_suggestion_implicit = + one option is to consistently remove the lifetime + +lint_mismatched_lifetime_syntaxes_suggestion_mixed = + one option is to remove the lifetime for references and use the anonymous lifetime for paths + lint_missing_fragment_specifier = missing fragment specifier lint_missing_unsafe_on_extern = extern blocks should be unsafe diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 47b80135bae..69e9f8e1b2c 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -39,7 +39,7 @@ pub use rustc_session::lint::builtin::*; use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass}; use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; -use rustc_span::{BytePos, Ident, InnerSpan, Span, Symbol, kw, sym}; +use rustc_span::{BytePos, DUMMY_SP, Ident, InnerSpan, Span, Symbol, kw, sym}; use rustc_target::asm::InlineAsmArch; use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt}; use rustc_trait_selection::traits::misc::type_allowed_to_implement_copy; @@ -635,7 +635,8 @@ fn type_implements_negative_copy_modulo_regions<'tcx>( typing_env: ty::TypingEnv<'tcx>, ) -> bool { let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); - let trait_ref = ty::TraitRef::new(tcx, tcx.require_lang_item(hir::LangItem::Copy, None), [ty]); + let trait_ref = + ty::TraitRef::new(tcx, tcx.require_lang_item(hir::LangItem::Copy, DUMMY_SP), [ty]); let pred = ty::TraitPredicate { trait_ref, polarity: ty::PredicatePolarity::Negative }; let obligation = traits::Obligation { cause: traits::ObligationCause::dummy(), diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index 71b621e8d20..60c477dd6c7 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -10,11 +10,11 @@ use rustc_errors::{ use rustc_middle::middle::stability; use rustc_middle::ty::TyCtxt; use rustc_session::Session; -use rustc_session::lint::{BuiltinLintDiag, ElidedLifetimeResolution}; -use rustc_span::{BytePos, kw}; +use rustc_session::lint::BuiltinLintDiag; +use rustc_span::BytePos; use tracing::debug; -use crate::lints::{self, ElidedNamedLifetime}; +use crate::lints; mod check_cfg; @@ -471,16 +471,5 @@ pub fn decorate_builtin_lint( BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by } => { lints::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.decorate_lint(diag) } - BuiltinLintDiag::ElidedNamedLifetimes { elided: (span, kind), resolution } => { - match resolution { - ElidedLifetimeResolution::Static => { - ElidedNamedLifetime { span, kind, name: kw::StaticLifetime, declaration: None } - } - ElidedLifetimeResolution::Param(name, declaration) => { - ElidedNamedLifetime { span, kind, name, declaration: Some(declaration) } - } - } - .decorate_lint(diag) - } } } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 0a52e42e442..c86f66cc9b0 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -55,6 +55,7 @@ mod invalid_from_utf8; mod late; mod let_underscore; mod levels; +mod lifetime_syntax; mod lints; mod macro_expr_fragment_specifier_2024_migration; mod map_unit_fn; @@ -96,6 +97,7 @@ use impl_trait_overcaptures::ImplTraitOvercaptures; use internal::*; use invalid_from_utf8::*; use let_underscore::*; +use lifetime_syntax::*; use macro_expr_fragment_specifier_2024_migration::*; use map_unit_fn::*; use multiple_supertrait_upcastable::*; @@ -246,6 +248,7 @@ late_lint_methods!( StaticMutRefs: StaticMutRefs, UnqualifiedLocalImports: UnqualifiedLocalImports, CheckTransmutes: CheckTransmutes, + LifetimeSyntax: LifetimeSyntax, ] ] ); @@ -353,6 +356,7 @@ fn register_builtins(store: &mut LintStore) { store.register_renamed("unused_tuple_struct_fields", "dead_code"); store.register_renamed("static_mut_ref", "static_mut_refs"); store.register_renamed("temporary_cstring_as_ptr", "dangling_pointers_from_temporaries"); + store.register_renamed("elided_named_lifetimes", "mismatched_lifetime_syntaxes"); // These were moved to tool lints, but rustc still sees them when compiling normally, before // tool lints are registered, so `check_tool_name_for_backwards_compat` doesn't work. Use diff --git a/compiler/rustc_lint/src/lifetime_syntax.rs b/compiler/rustc_lint/src/lifetime_syntax.rs new file mode 100644 index 00000000000..31b038e6a46 --- /dev/null +++ b/compiler/rustc_lint/src/lifetime_syntax.rs @@ -0,0 +1,503 @@ +use rustc_data_structures::fx::FxIndexMap; +use rustc_hir::intravisit::{self, Visitor}; +use rustc_hir::{self as hir, LifetimeSource}; +use rustc_session::{declare_lint, declare_lint_pass}; +use rustc_span::Span; +use tracing::instrument; + +use crate::{LateContext, LateLintPass, LintContext, lints}; + +declare_lint! { + /// The `mismatched_lifetime_syntaxes` lint detects when the same + /// lifetime is referred to by different syntaxes between function + /// arguments and return values. + /// + /// The three kinds of syntaxes are: + /// + /// 1. Named lifetimes. These are references (`&'a str`) or paths + /// (`Person<'a>`) that use a lifetime with a name, such as + /// `'static` or `'a`. + /// + /// 2. Elided lifetimes. These are references with no explicit + /// lifetime (`&str`), references using the anonymous lifetime + /// (`&'_ str`), and paths using the anonymous lifetime + /// (`Person<'_>`). + /// + /// 3. Hidden lifetimes. These are paths that do not contain any + /// visual indication that it contains a lifetime (`Person`). + /// + /// ### Example + /// + /// ```rust,compile_fail + /// #![deny(mismatched_lifetime_syntaxes)] + /// + /// pub fn mixing_named_with_elided(v: &'static u8) -> &u8 { + /// v + /// } + /// + /// struct Person<'a> { + /// name: &'a str, + /// } + /// + /// pub fn mixing_hidden_with_elided(v: Person) -> Person<'_> { + /// v + /// } + /// + /// struct Foo; + /// + /// impl Foo { + /// // Lifetime elision results in the output lifetime becoming + /// // `'static`, which is not what was intended. + /// pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 { + /// unsafe { &mut *(x as *mut _) } + /// } + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Lifetime elision is useful because it frees you from having to + /// give each lifetime its own name and show the relation of input + /// and output lifetimes for common cases. However, a lifetime + /// that uses inconsistent syntax between related arguments and + /// return values is more confusing. + /// + /// In certain `unsafe` code, lifetime elision combined with + /// inconsistent lifetime syntax may result in unsound code. + pub MISMATCHED_LIFETIME_SYNTAXES, + Warn, + "detects when a lifetime uses different syntax between arguments and return values" +} + +declare_lint_pass!(LifetimeSyntax => [MISMATCHED_LIFETIME_SYNTAXES]); + +impl<'tcx> LateLintPass<'tcx> for LifetimeSyntax { + #[instrument(skip_all)] + fn check_fn( + &mut self, + cx: &LateContext<'tcx>, + _: hir::intravisit::FnKind<'tcx>, + fd: &'tcx hir::FnDecl<'tcx>, + _: &'tcx hir::Body<'tcx>, + _: rustc_span::Span, + _: rustc_span::def_id::LocalDefId, + ) { + let mut input_map = Default::default(); + let mut output_map = Default::default(); + + for input in fd.inputs { + LifetimeInfoCollector::collect(input, &mut input_map); + } + + if let hir::FnRetTy::Return(output) = fd.output { + LifetimeInfoCollector::collect(output, &mut output_map); + } + + report_mismatches(cx, &input_map, &output_map); + } +} + +#[instrument(skip_all)] +fn report_mismatches<'tcx>( + cx: &LateContext<'tcx>, + inputs: &LifetimeInfoMap<'tcx>, + outputs: &LifetimeInfoMap<'tcx>, +) { + for (resolved_lifetime, output_info) in outputs { + if let Some(input_info) = inputs.get(resolved_lifetime) { + if !lifetimes_use_matched_syntax(input_info, output_info) { + emit_mismatch_diagnostic(cx, input_info, output_info); + } + } + } +} + +fn lifetimes_use_matched_syntax(input_info: &[Info<'_>], output_info: &[Info<'_>]) -> bool { + // Categorize lifetimes into source/syntax buckets. + let mut n_hidden = 0; + let mut n_elided = 0; + let mut n_named = 0; + + for info in input_info.iter().chain(output_info) { + use LifetimeSource::*; + use hir::LifetimeSyntax::*; + + let syntax_source = (info.lifetime.syntax, info.lifetime.source); + + match syntax_source { + // Ignore any other kind of lifetime. + (_, Other) => continue, + + // E.g. `&T`. + (Implicit, Reference | OutlivesBound | PreciseCapturing) | + // E.g. `&'_ T`. + (ExplicitAnonymous, Reference | OutlivesBound | PreciseCapturing) | + // E.g. `ContainsLifetime<'_>`. + (ExplicitAnonymous, Path { .. }) => n_elided += 1, + + // E.g. `ContainsLifetime`. + (Implicit, Path { .. }) => n_hidden += 1, + + // E.g. `&'a T`. + (ExplicitBound, Reference | OutlivesBound | PreciseCapturing) | + // E.g. `ContainsLifetime<'a>`. + (ExplicitBound, Path { .. }) => n_named += 1, + }; + } + + let syntax_counts = (n_hidden, n_elided, n_named); + tracing::debug!(?syntax_counts); + + matches!(syntax_counts, (_, 0, 0) | (0, _, 0) | (0, 0, _)) +} + +fn emit_mismatch_diagnostic<'tcx>( + cx: &LateContext<'tcx>, + input_info: &[Info<'_>], + output_info: &[Info<'_>], +) { + // There can only ever be zero or one bound lifetime + // for a given lifetime resolution. + let mut bound_lifetime = None; + + // We offer the following kinds of suggestions (when appropriate + // such that the suggestion wouldn't violate the lint): + // + // 1. Every lifetime becomes named, when there is already a + // user-provided name. + // + // 2. A "mixed" signature, where references become implicit + // and paths become explicitly anonymous. + // + // 3. Every lifetime becomes implicit. + // + // 4. Every lifetime becomes explicitly anonymous. + // + // Number 2 is arguably the most common pattern and the one we + // should push strongest. Number 3 is likely the next most common, + // followed by number 1. Coming in at a distant last would be + // number 4. + // + // Beyond these, there are variants of acceptable signatures that + // we won't suggest because they are very low-value. For example, + // we will never suggest `fn(&T1, &'_ T2) -> &T3` even though that + // would pass the lint. + // + // The following collections are the lifetime instances that we + // suggest changing to a given alternate style. + + // 1. Convert all to named. + let mut suggest_change_to_explicit_bound = Vec::new(); + + // 2. Convert to mixed. We track each kind of change separately. + let mut suggest_change_to_mixed_implicit = Vec::new(); + let mut suggest_change_to_mixed_explicit_anonymous = Vec::new(); + + // 3. Convert all to implicit. + let mut suggest_change_to_implicit = Vec::new(); + + // 4. Convert all to explicit anonymous. + let mut suggest_change_to_explicit_anonymous = Vec::new(); + + // Some styles prevent using implicit syntax at all. + let mut allow_suggesting_implicit = true; + + // It only makes sense to suggest mixed if we have both sources. + let mut saw_a_reference = false; + let mut saw_a_path = false; + + for info in input_info.iter().chain(output_info) { + use LifetimeSource::*; + use hir::LifetimeSyntax::*; + + let syntax_source = (info.lifetime.syntax, info.lifetime.source); + + if let (_, Other) = syntax_source { + // Ignore any other kind of lifetime. + continue; + } + + if let (ExplicitBound, _) = syntax_source { + bound_lifetime = Some(info); + } + + match syntax_source { + // E.g. `&T`. + (Implicit, Reference) => { + suggest_change_to_explicit_anonymous.push(info); + suggest_change_to_explicit_bound.push(info); + } + + // E.g. `&'_ T`. + (ExplicitAnonymous, Reference) => { + suggest_change_to_implicit.push(info); + suggest_change_to_mixed_implicit.push(info); + suggest_change_to_explicit_bound.push(info); + } + + // E.g. `ContainsLifetime`. + (Implicit, Path { .. }) => { + suggest_change_to_mixed_explicit_anonymous.push(info); + suggest_change_to_explicit_anonymous.push(info); + suggest_change_to_explicit_bound.push(info); + } + + // E.g. `ContainsLifetime<'_>`. + (ExplicitAnonymous, Path { .. }) => { + suggest_change_to_explicit_bound.push(info); + } + + // E.g. `&'a T`. + (ExplicitBound, Reference) => { + suggest_change_to_implicit.push(info); + suggest_change_to_mixed_implicit.push(info); + suggest_change_to_explicit_anonymous.push(info); + } + + // E.g. `ContainsLifetime<'a>`. + (ExplicitBound, Path { .. }) => { + suggest_change_to_mixed_explicit_anonymous.push(info); + suggest_change_to_explicit_anonymous.push(info); + } + + (Implicit, OutlivesBound | PreciseCapturing) => { + panic!("This syntax / source combination is not possible"); + } + + // E.g. `+ '_`, `+ use<'_>`. + (ExplicitAnonymous, OutlivesBound | PreciseCapturing) => { + suggest_change_to_explicit_bound.push(info); + } + + // E.g. `+ 'a`, `+ use<'a>`. + (ExplicitBound, OutlivesBound | PreciseCapturing) => { + suggest_change_to_mixed_explicit_anonymous.push(info); + suggest_change_to_explicit_anonymous.push(info); + } + + (_, Other) => { + panic!("This syntax / source combination has already been skipped"); + } + } + + if matches!(syntax_source, (_, Path { .. } | OutlivesBound | PreciseCapturing)) { + allow_suggesting_implicit = false; + } + + match syntax_source { + (_, Reference) => saw_a_reference = true, + (_, Path { .. }) => saw_a_path = true, + _ => {} + } + } + + let make_implicit_suggestions = + |infos: &[&Info<'_>]| infos.iter().map(|i| i.removing_span()).collect::<Vec<_>>(); + + let inputs = input_info.iter().map(|info| info.reporting_span()).collect(); + let outputs = output_info.iter().map(|info| info.reporting_span()).collect(); + + let explicit_bound_suggestion = bound_lifetime.map(|info| { + build_mismatch_suggestion(info.lifetime_name(), &suggest_change_to_explicit_bound) + }); + + let is_bound_static = bound_lifetime.is_some_and(|info| info.is_static()); + + tracing::debug!(?bound_lifetime, ?explicit_bound_suggestion, ?is_bound_static); + + let should_suggest_mixed = + // Do we have a mixed case? + (saw_a_reference && saw_a_path) && + // Is there anything to change? + (!suggest_change_to_mixed_implicit.is_empty() || + !suggest_change_to_mixed_explicit_anonymous.is_empty()) && + // If we have `'static`, we don't want to remove it. + !is_bound_static; + + let mixed_suggestion = should_suggest_mixed.then(|| { + let implicit_suggestions = make_implicit_suggestions(&suggest_change_to_mixed_implicit); + + let explicit_anonymous_suggestions = suggest_change_to_mixed_explicit_anonymous + .iter() + .map(|info| info.suggestion("'_")) + .collect(); + + lints::MismatchedLifetimeSyntaxesSuggestion::Mixed { + implicit_suggestions, + explicit_anonymous_suggestions, + tool_only: false, + } + }); + + tracing::debug!( + ?suggest_change_to_mixed_implicit, + ?suggest_change_to_mixed_explicit_anonymous, + ?mixed_suggestion, + ); + + let should_suggest_implicit = + // Is there anything to change? + !suggest_change_to_implicit.is_empty() && + // We never want to hide the lifetime in a path (or similar). + allow_suggesting_implicit && + // If we have `'static`, we don't want to remove it. + !is_bound_static; + + let implicit_suggestion = should_suggest_implicit.then(|| { + let suggestions = make_implicit_suggestions(&suggest_change_to_implicit); + + lints::MismatchedLifetimeSyntaxesSuggestion::Implicit { suggestions, tool_only: false } + }); + + tracing::debug!( + ?should_suggest_implicit, + ?suggest_change_to_implicit, + allow_suggesting_implicit, + ?implicit_suggestion, + ); + + let should_suggest_explicit_anonymous = + // Is there anything to change? + !suggest_change_to_explicit_anonymous.is_empty() && + // If we have `'static`, we don't want to remove it. + !is_bound_static; + + let explicit_anonymous_suggestion = should_suggest_explicit_anonymous + .then(|| build_mismatch_suggestion("'_", &suggest_change_to_explicit_anonymous)); + + tracing::debug!( + ?should_suggest_explicit_anonymous, + ?suggest_change_to_explicit_anonymous, + ?explicit_anonymous_suggestion, + ); + + let lifetime_name = bound_lifetime.map(|info| info.lifetime_name()).unwrap_or("'_").to_owned(); + + // We can produce a number of suggestions which may overwhelm + // the user. Instead, we order the suggestions based on Rust + // idioms. The "best" choice is shown to the user and the + // remaining choices are shown to tools only. + let mut suggestions = Vec::new(); + suggestions.extend(explicit_bound_suggestion); + suggestions.extend(mixed_suggestion); + suggestions.extend(implicit_suggestion); + suggestions.extend(explicit_anonymous_suggestion); + + cx.emit_span_lint( + MISMATCHED_LIFETIME_SYNTAXES, + Vec::clone(&inputs), + lints::MismatchedLifetimeSyntaxes { lifetime_name, inputs, outputs, suggestions }, + ); +} + +fn build_mismatch_suggestion( + lifetime_name: &str, + infos: &[&Info<'_>], +) -> lints::MismatchedLifetimeSyntaxesSuggestion { + let lifetime_name = lifetime_name.to_owned(); + + let suggestions = infos.iter().map(|info| info.suggestion(&lifetime_name)).collect(); + + lints::MismatchedLifetimeSyntaxesSuggestion::Explicit { + lifetime_name, + suggestions, + tool_only: false, + } +} + +#[derive(Debug)] +struct Info<'tcx> { + type_span: Span, + referenced_type_span: Option<Span>, + lifetime: &'tcx hir::Lifetime, +} + +impl<'tcx> Info<'tcx> { + fn lifetime_name(&self) -> &str { + self.lifetime.ident.as_str() + } + + fn is_static(&self) -> bool { + self.lifetime.is_static() + } + + /// When reporting a lifetime that is implicit, we expand the span + /// to include the type. Otherwise we end up pointing at nothing, + /// which is a bit confusing. + fn reporting_span(&self) -> Span { + if self.lifetime.is_implicit() { self.type_span } else { self.lifetime.ident.span } + } + + /// When removing an explicit lifetime from a reference, + /// we want to remove the whitespace after the lifetime. + /// + /// ```rust + /// fn x(a: &'_ u8) {} + /// ``` + /// + /// Should become: + /// + /// ```rust + /// fn x(a: &u8) {} + /// ``` + // FIXME: Ideally, we'd also remove the lifetime declaration. + fn removing_span(&self) -> Span { + let mut span = self.suggestion("'dummy").0; + + if let Some(referenced_type_span) = self.referenced_type_span { + span = span.until(referenced_type_span); + } + + span + } + + fn suggestion(&self, lifetime_name: &str) -> (Span, String) { + self.lifetime.suggestion(lifetime_name) + } +} + +type LifetimeInfoMap<'tcx> = FxIndexMap<&'tcx hir::LifetimeKind, Vec<Info<'tcx>>>; + +struct LifetimeInfoCollector<'a, 'tcx> { + type_span: Span, + referenced_type_span: Option<Span>, + map: &'a mut LifetimeInfoMap<'tcx>, +} + +impl<'a, 'tcx> LifetimeInfoCollector<'a, 'tcx> { + fn collect(ty: &'tcx hir::Ty<'tcx>, map: &'a mut LifetimeInfoMap<'tcx>) { + let mut this = Self { type_span: ty.span, referenced_type_span: None, map }; + + intravisit::walk_unambig_ty(&mut this, ty); + } +} + +impl<'a, 'tcx> Visitor<'tcx> for LifetimeInfoCollector<'a, 'tcx> { + #[instrument(skip(self))] + fn visit_lifetime(&mut self, lifetime: &'tcx hir::Lifetime) { + let type_span = self.type_span; + let referenced_type_span = self.referenced_type_span; + + let info = Info { type_span, referenced_type_span, lifetime }; + + self.map.entry(&lifetime.kind).or_default().push(info); + } + + #[instrument(skip(self))] + fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, hir::AmbigArg>) -> Self::Result { + let old_type_span = self.type_span; + let old_referenced_type_span = self.referenced_type_span; + + self.type_span = ty.span; + if let hir::TyKind::Ref(_, ty) = ty.kind { + self.referenced_type_span = Some(ty.ty.span); + } + + intravisit::walk_ty(self, ty); + + self.type_span = old_type_span; + self.referenced_type_span = old_referenced_type_span; + } +} diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 10d0e2c93a8..9d3c74a9a2b 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -8,17 +8,17 @@ use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagMessage, DiagStyledString, ElidedLifetimeInPathSubdiag, EmissionGuarantee, LintDiagnostic, MultiSpan, Subdiagnostic, SuggestionStyle, }; +use rustc_hir as hir; use rustc_hir::def::Namespace; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::VisitorExt; -use rustc_hir::{self as hir, MissingLifetimeKind}; use rustc_macros::{LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::inhabitedness::InhabitedPredicate; use rustc_middle::ty::{Clause, PolyExistentialTraitRef, Ty, TyCtxt}; use rustc_session::Session; use rustc_session::lint::AmbiguityErrorDiag; use rustc_span::edition::Edition; -use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol, kw, sym}; +use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol, sym}; use crate::builtin::{InitError, ShorthandAssocTyCollector, TypeAliasBounds}; use crate::errors::{OverruledAttributeSub, RequestedLevel}; @@ -2752,58 +2752,6 @@ pub(crate) struct ElidedLifetimesInPaths { pub subdiag: ElidedLifetimeInPathSubdiag, } -pub(crate) struct ElidedNamedLifetime { - pub span: Span, - pub kind: MissingLifetimeKind, - pub name: Symbol, - pub declaration: Option<Span>, -} - -impl<G: EmissionGuarantee> LintDiagnostic<'_, G> for ElidedNamedLifetime { - fn decorate_lint(self, diag: &mut rustc_errors::Diag<'_, G>) { - let Self { span, kind, name, declaration } = self; - diag.primary_message(fluent::lint_elided_named_lifetime); - diag.arg("name", name); - diag.span_label(span, fluent::lint_label_elided); - if let Some(declaration) = declaration { - diag.span_label(declaration, fluent::lint_label_named); - } - // FIXME(GrigorenkoPV): this `if` and `return` should be removed, - // but currently this lint's suggestions can conflict with those of `clippy::needless_lifetimes`: - // https://github.com/rust-lang/rust/pull/129840#issuecomment-2323349119 - // HACK: `'static` suggestions will never sonflict, emit only those for now. - if name != kw::StaticLifetime { - return; - } - match kind { - MissingLifetimeKind::Underscore => diag.span_suggestion_verbose( - span, - fluent::lint_suggestion, - format!("{name}"), - Applicability::MachineApplicable, - ), - MissingLifetimeKind::Ampersand => diag.span_suggestion_verbose( - span.shrink_to_hi(), - fluent::lint_suggestion, - format!("{name} "), - Applicability::MachineApplicable, - ), - MissingLifetimeKind::Comma => diag.span_suggestion_verbose( - span.shrink_to_hi(), - fluent::lint_suggestion, - format!("{name}, "), - Applicability::MachineApplicable, - ), - MissingLifetimeKind::Brackets => diag.span_suggestion_verbose( - span.shrink_to_hi(), - fluent::lint_suggestion, - format!("<{name}>"), - Applicability::MachineApplicable, - ), - }; - } -} - #[derive(LintDiagnostic)] #[diag(lint_invalid_crate_type_value)] pub(crate) struct UnknownCrateTypes { @@ -3241,3 +3189,128 @@ pub(crate) struct ReservedMultihash { #[suggestion(code = " ", applicability = "machine-applicable")] pub suggestion: Span, } + +#[derive(Debug)] +pub(crate) struct MismatchedLifetimeSyntaxes { + pub lifetime_name: String, + pub inputs: Vec<Span>, + pub outputs: Vec<Span>, + + pub suggestions: Vec<MismatchedLifetimeSyntaxesSuggestion>, +} + +impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for MismatchedLifetimeSyntaxes { + fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) { + diag.primary_message(fluent::lint_mismatched_lifetime_syntaxes); + + diag.arg("lifetime_name", self.lifetime_name); + + diag.arg("n_inputs", self.inputs.len()); + for input in self.inputs { + let a = diag.eagerly_translate(fluent::lint_label_mismatched_lifetime_syntaxes_inputs); + diag.span_label(input, a); + } + + diag.arg("n_outputs", self.outputs.len()); + for output in self.outputs { + let a = diag.eagerly_translate(fluent::lint_label_mismatched_lifetime_syntaxes_outputs); + diag.span_label(output, a); + } + + let mut suggestions = self.suggestions.into_iter(); + if let Some(s) = suggestions.next() { + diag.subdiagnostic(s); + + for mut s in suggestions { + s.make_tool_only(); + diag.subdiagnostic(s); + } + } + } +} + +#[derive(Debug)] +pub(crate) enum MismatchedLifetimeSyntaxesSuggestion { + Implicit { + suggestions: Vec<Span>, + tool_only: bool, + }, + + Mixed { + implicit_suggestions: Vec<Span>, + explicit_anonymous_suggestions: Vec<(Span, String)>, + tool_only: bool, + }, + + Explicit { + lifetime_name: String, + suggestions: Vec<(Span, String)>, + tool_only: bool, + }, +} + +impl MismatchedLifetimeSyntaxesSuggestion { + fn make_tool_only(&mut self) { + use MismatchedLifetimeSyntaxesSuggestion::*; + + let tool_only = match self { + Implicit { tool_only, .. } | Mixed { tool_only, .. } | Explicit { tool_only, .. } => { + tool_only + } + }; + + *tool_only = true; + } +} + +impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion { + fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) { + use MismatchedLifetimeSyntaxesSuggestion::*; + + let style = |tool_only| { + if tool_only { SuggestionStyle::CompletelyHidden } else { SuggestionStyle::ShowAlways } + }; + + match self { + Implicit { suggestions, tool_only } => { + let suggestions = suggestions.into_iter().map(|s| (s, String::new())).collect(); + diag.multipart_suggestion_with_style( + fluent::lint_mismatched_lifetime_syntaxes_suggestion_implicit, + suggestions, + Applicability::MachineApplicable, + style(tool_only), + ); + } + + Mixed { implicit_suggestions, explicit_anonymous_suggestions, tool_only } => { + let implicit_suggestions = + implicit_suggestions.into_iter().map(|s| (s, String::new())); + + let suggestions = + implicit_suggestions.chain(explicit_anonymous_suggestions).collect(); + + diag.multipart_suggestion_with_style( + fluent::lint_mismatched_lifetime_syntaxes_suggestion_mixed, + suggestions, + Applicability::MachineApplicable, + style(tool_only), + ); + } + + Explicit { lifetime_name, suggestions, tool_only } => { + diag.arg("lifetime_name", lifetime_name); + + let msg = diag.eagerly_translate( + fluent::lint_mismatched_lifetime_syntaxes_suggestion_explicit, + ); + + diag.multipart_suggestion_with_style( + msg, + suggestions, + Applicability::MachineApplicable, + style(tool_only), + ); + } + } + } +} diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 1b14157c5f0..843d5778421 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -40,7 +40,6 @@ declare_lint_pass! { DUPLICATE_MACRO_ATTRIBUTES, ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, ELIDED_LIFETIMES_IN_PATHS, - ELIDED_NAMED_LIFETIMES, EXPLICIT_BUILTIN_CFGS_IN_FLAGS, EXPORTED_PRIVATE_DEPENDENCIES, FFI_UNWIND_CALLS, @@ -1833,38 +1832,6 @@ declare_lint! { } declare_lint! { - /// The `elided_named_lifetimes` lint detects when an elided - /// lifetime ends up being a named lifetime, such as `'static` - /// or some lifetime parameter `'a`. - /// - /// ### Example - /// - /// ```rust,compile_fail - /// #![deny(elided_named_lifetimes)] - /// struct Foo; - /// impl Foo { - /// pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 { - /// unsafe { &mut *(x as *mut _) } - /// } - /// } - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// Lifetime elision is quite useful, because it frees you from having - /// to give each lifetime its own name, but sometimes it can produce - /// somewhat surprising resolutions. In safe code, it is mostly okay, - /// because the borrow checker prevents any unsoundness, so the worst - /// case scenario is you get a confusing error message in some other place. - /// But with `unsafe` code, such unexpected resolutions may lead to unsound code. - pub ELIDED_NAMED_LIFETIMES, - Warn, - "detects when an elided lifetime gets resolved to be `'static` or some named parameter" -} - -declare_lint! { /// The `bare_trait_objects` lint suggests using `dyn Trait` for trait /// objects. /// diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index e19bf59e543..1d9b7a7fcb9 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -9,7 +9,7 @@ use rustc_data_structures::stable_hasher::{ use rustc_error_messages::{DiagMessage, MultiSpan}; use rustc_hir::def::Namespace; use rustc_hir::def_id::DefPathHash; -use rustc_hir::{HashStableContext, HirId, ItemLocalId, MissingLifetimeKind}; +use rustc_hir::{HashStableContext, HirId, ItemLocalId}; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; pub use rustc_span::edition::Edition; use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol, sym}; @@ -610,12 +610,6 @@ pub enum DeprecatedSinceKind { InVersion(String), } -#[derive(Debug)] -pub enum ElidedLifetimeResolution { - Static, - Param(Symbol, Span), -} - // This could be a closure, but then implementing derive trait // becomes hacky (and it gets allocated). #[derive(Debug)] @@ -628,10 +622,6 @@ pub enum BuiltinLintDiag { }, MacroExpandedMacroExportsAccessedByAbsolutePaths(Span), ElidedLifetimesInPaths(usize, Span, bool, Span), - ElidedNamedLifetimes { - elided: (Span, MissingLifetimeKind), - resolution: ElidedLifetimeResolution, - }, UnknownCrateTypes { span: Span, candidate: Option<Symbol>, diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index bd315577efb..6c6b12fed67 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -95,7 +95,7 @@ pub(crate) struct StrictCoherenceNeedsNegativeCoherence { #[diag(middle_requires_lang_item)] pub(crate) struct RequiresLangItem { #[primary_span] - pub span: Option<Span>, + pub span: Span, pub name: Symbol, } diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs index 0f92c1910f1..93264f02cc2 100644 --- a/compiler/rustc_middle/src/middle/lang_items.rs +++ b/compiler/rustc_middle/src/middle/lang_items.rs @@ -17,7 +17,7 @@ use crate::ty::{self, TyCtxt}; impl<'tcx> TyCtxt<'tcx> { /// Returns the `DefId` for a given `LangItem`. /// If not found, fatally aborts compilation. - pub fn require_lang_item(self, lang_item: LangItem, span: Option<Span>) -> DefId { + pub fn require_lang_item(self, lang_item: LangItem, span: Span) -> DefId { self.lang_items().get(lang_item).unwrap_or_else(|| { self.dcx().emit_fatal(crate::error::RequiresLangItem { span, name: lang_item.name() }); }) diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 06e41e64fdc..d98b40f0fcf 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -835,7 +835,7 @@ impl<'tcx> BinOp { &BinOp::Cmp => { // these should be integer-like types of the same size. assert_eq!(lhs_ty, rhs_ty); - tcx.ty_ordering_enum(None) + tcx.ty_ordering_enum(DUMMY_SP) } } } diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index a61a6c571a2..3bacdfe5ac8 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -128,8 +128,8 @@ impl OverloadedDeref { /// for this overloaded deref's mutability. pub fn method_call<'tcx>(&self, tcx: TyCtxt<'tcx>) -> DefId { let trait_def_id = match self.mutbl { - hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, None), - hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, None), + hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, self.span), + hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, self.span), }; tcx.associated_items(trait_def_id) .in_definition_order() diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 57b20a1bba6..0b1e9852d2a 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -458,7 +458,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { } fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId { - self.require_lang_item(trait_lang_item_to_lang_item(lang_item), None) + self.require_lang_item(trait_lang_item_to_lang_item(lang_item), DUMMY_SP) } fn is_lang_item(self, def_id: DefId, lang_item: TraitSolverLangItem) -> bool { @@ -1710,7 +1710,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Gets a `Ty` representing the [`LangItem::OrderingEnum`] #[track_caller] - pub fn ty_ordering_enum(self, span: Option<Span>) -> Ty<'tcx> { + pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> { let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span); self.type_of(ordering_enum).no_bound_vars().unwrap() } @@ -2253,7 +2253,7 @@ impl<'tcx> TyCtxt<'tcx> { Ty::new_imm_ref( self, self.lifetimes.re_static, - self.type_of(self.require_lang_item(LangItem::PanicLocation, None)) + self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP)) .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])), ) } @@ -2712,7 +2712,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Given a `ty`, return whether it's an `impl Future<...>`. pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool { let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false }; - let future_trait = self.require_lang_item(LangItem::Future, None); + let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP); self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| { let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else { diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 0d99a1b5149..5ba4e5446e9 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -786,7 +786,7 @@ impl<'tcx> Instance<'tcx> { } pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> { - let def_id = tcx.require_lang_item(LangItem::DropInPlace, None); + let def_id = tcx.require_lang_item(LangItem::DropInPlace, DUMMY_SP); let args = tcx.mk_args(&[ty.into()]); Instance::expect_resolve( tcx, @@ -798,7 +798,7 @@ impl<'tcx> Instance<'tcx> { } pub fn resolve_async_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> { - let def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, None); + let def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, DUMMY_SP); let args = tcx.mk_args(&[ty.into()]); Instance::expect_resolve( tcx, @@ -824,7 +824,7 @@ impl<'tcx> Instance<'tcx> { closure_did: DefId, args: ty::GenericArgsRef<'tcx>, ) -> Instance<'tcx> { - let fn_once = tcx.require_lang_item(LangItem::FnOnce, None); + let fn_once = tcx.require_lang_item(LangItem::FnOnce, DUMMY_SP); let call_once = tcx .associated_items(fn_once) .in_definition_order() diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 404674c359e..cbf545c01c5 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -593,7 +593,7 @@ impl<'tcx> Ty<'tcx> { ty: Ty<'tcx>, mutbl: ty::Mutability, ) -> Ty<'tcx> { - let pin = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, None)); + let pin = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, DUMMY_SP)); Ty::new_adt(tcx, pin, tcx.mk_args(&[Ty::new_ref(tcx, r, ty, mutbl).into()])) } @@ -857,19 +857,19 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn new_box(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { - let def_id = tcx.require_lang_item(LangItem::OwnedBox, None); + let def_id = tcx.require_lang_item(LangItem::OwnedBox, DUMMY_SP); Ty::new_generic_adt(tcx, def_id, ty) } #[inline] pub fn new_maybe_uninit(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { - let def_id = tcx.require_lang_item(LangItem::MaybeUninit, None); + let def_id = tcx.require_lang_item(LangItem::MaybeUninit, DUMMY_SP); Ty::new_generic_adt(tcx, def_id, ty) } /// Creates a `&mut Context<'_>` [`Ty`] with erased lifetimes. pub fn new_task_context(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { - let context_did = tcx.require_lang_item(LangItem::Context, None); + let context_did = tcx.require_lang_item(LangItem::Context, DUMMY_SP); let context_adt_ref = tcx.adt_def(context_did); let context_args = tcx.mk_args(&[tcx.lifetimes.re_erased.into()]); let context_ty = Ty::new_adt(tcx, context_adt_ref, context_args); @@ -1549,7 +1549,7 @@ impl<'tcx> Ty<'tcx> { ty::Param(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => { let assoc_items = tcx.associated_item_def_ids( - tcx.require_lang_item(hir::LangItem::DiscriminantKind, None), + tcx.require_lang_item(hir::LangItem::DiscriminantKind, DUMMY_SP), ); Ty::new_projection_from_args(tcx, assoc_items[0], tcx.mk_args(&[self.into()])) } @@ -1629,7 +1629,7 @@ impl<'tcx> Ty<'tcx> { ty::Str | ty::Slice(_) => Ok(tcx.types.usize), ty::Dynamic(_, _, ty::Dyn) => { - let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None); + let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, DUMMY_SP); Ok(tcx.type_of(dyn_metadata).instantiate(tcx, &[tail.into()])) } @@ -1683,7 +1683,7 @@ impl<'tcx> Ty<'tcx> { match pointee_ty.ptr_metadata_ty_or_tail(tcx, |x| x) { Ok(metadata_ty) => metadata_ty, Err(tail_ty) => { - let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); + let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, DUMMY_SP); Ty::new_projection(tcx, metadata_def_id, [tail_ty]) } } diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs index 5a97b08db28..b23bc089cd4 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs @@ -145,7 +145,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // malloc some memory of suitable size and align: let exchange_malloc = Operand::function_handle( tcx, - tcx.require_lang_item(LangItem::ExchangeMalloc, Some(expr_span)), + tcx.require_lang_item(LangItem::ExchangeMalloc, expr_span), [], expr_span, ); diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs index a9a07997410..2074fbce0ae 100644 --- a/compiler/rustc_mir_build/src/builder/expr/into.rs +++ b/compiler/rustc_mir_build/src/builder/expr/into.rs @@ -307,7 +307,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } else if this.infcx.type_is_use_cloned_modulo_regions(this.param_env, ty) { // Convert `expr.use` to a call like `Clone::clone(&expr)` let success = this.cfg.start_new_block(); - let clone_trait = this.tcx.require_lang_item(LangItem::Clone, None); + let clone_trait = this.tcx.require_lang_item(LangItem::Clone, span); let clone_fn = this.tcx.associated_item_def_ids(clone_trait)[0]; let func = Operand::function_handle(this.tcx, clone_fn, [ty.into()], expr_span); let ref_ty = Ty::new_imm_ref(this.tcx, this.tcx.lifetimes.re_erased, ty); diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index 210b9cce581..a4609a6053e 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -364,7 +364,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let borrow_kind = super::util::ref_pat_borrow_kind(mutability); let source_info = self.source_info(span); let re_erased = self.tcx.lifetimes.re_erased; - let trait_item = self.tcx.require_lang_item(trait_item, None); + let trait_item = self.tcx.require_lang_item(trait_item, span); let method = trait_method(self.tcx, trait_item, method, [ty]); let ref_src = self.temp(Ty::new_ref(self.tcx, re_erased, ty, mutability), span); // `let ref_src = &src_place;` @@ -437,7 +437,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { val: Operand<'tcx>, ) { let str_ty = self.tcx.types.str_; - let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span)); + let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, source_info.span); let method = trait_method(self.tcx, eq_def_id, sym::eq, [str_ty, str_ty]); let bool_ty = self.tcx.types.bool; diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 226dc920a49..3baeccf6409 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -38,7 +38,10 @@ impl<'tcx> ThirBuildCx<'tcx> { } pub(crate) fn mirror_exprs(&mut self, exprs: &'tcx [hir::Expr<'tcx>]) -> Box<[ExprId]> { - exprs.iter().map(|expr| self.mirror_expr_inner(expr)).collect() + // `mirror_exprs` may also recurse deeply, so it needs protection from stack overflow. + // Note that we *could* forward to `mirror_expr` for that, but we can consolidate the + // overhead of stack growth by doing it outside the iteration. + ensure_sufficient_stack(|| exprs.iter().map(|expr| self.mirror_expr_inner(expr)).collect()) } #[instrument(level = "trace", skip(self, hir_expr))] @@ -220,7 +223,7 @@ impl<'tcx> ThirBuildCx<'tcx> { }); // kind = Pin { __pointer: pointer } - let pin_did = self.tcx.require_lang_item(rustc_hir::LangItem::Pin, Some(span)); + let pin_did = self.tcx.require_lang_item(rustc_hir::LangItem::Pin, span); let args = self.tcx.mk_args(&[new_pin_target.into()]); let kind = ExprKind::Adt(Box::new(AdtExpr { adt_def: self.tcx.adt_def(pin_did), diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 8c817605847..24d4136c642 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -189,7 +189,7 @@ impl<'tcx> ThirBuildCx<'tcx> { // C-variadic fns also have a `VaList` input that's not listed in `fn_sig` // (as it's created inside the body itself, not passed in from outside). let ty = if fn_decl.c_variadic && index == fn_decl.inputs.len() { - let va_list_did = self.tcx.require_lang_item(LangItem::VaList, Some(param.span)); + let va_list_did = self.tcx.require_lang_item(LangItem::VaList, param.span); self.tcx .type_of(va_list_did) diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 84a0190a7fa..003ad170861 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::{ }; use rustc_middle::{mir, span_bug}; use rustc_span::def_id::DefId; -use rustc_span::{Span, sym}; +use rustc_span::{DUMMY_SP, Span, sym}; use rustc_trait_selection::traits::ObligationCause; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use tracing::{debug, instrument, trace}; @@ -480,8 +480,9 @@ fn type_has_partial_eq_impl<'tcx>( // (If there isn't, then we can safely issue a hard // error, because that's never worked, due to compiler // using `PartialEq::eq` in this scenario in the past.) - let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, None); - let structural_partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::StructuralPeq, None); + let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, DUMMY_SP); + let structural_partial_eq_trait_id = + tcx.require_lang_item(hir::LangItem::StructuralPeq, DUMMY_SP); let partial_eq_obligation = Obligation::new( tcx, diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index cddb2f84778..d5d0d56f528 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -225,7 +225,7 @@ impl<'tcx> TransformVisitor<'tcx> { CoroutineKind::Coroutine(_) => span_bug!(body.span, "`Coroutine`s cannot be fused"), // `gen` continues return `None` CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => { - let option_def_id = self.tcx.require_lang_item(LangItem::Option, None); + let option_def_id = self.tcx.require_lang_item(LangItem::Option, body.span); make_aggregate_adt( option_def_id, VariantIdx::ZERO, @@ -242,7 +242,7 @@ impl<'tcx> TransformVisitor<'tcx> { span: source_info.span, const_: Const::Unevaluated( UnevaluatedConst::new( - self.tcx.require_lang_item(LangItem::AsyncGenFinished, None), + self.tcx.require_lang_item(LangItem::AsyncGenFinished, body.span), self.tcx.mk_args(&[yield_ty.into()]), ), self.old_yield_ty, @@ -282,7 +282,7 @@ impl<'tcx> TransformVisitor<'tcx> { const ONE: VariantIdx = VariantIdx::from_usize(1); let rvalue = match self.coroutine_kind { CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => { - let poll_def_id = self.tcx.require_lang_item(LangItem::Poll, None); + let poll_def_id = self.tcx.require_lang_item(LangItem::Poll, source_info.span); let args = self.tcx.mk_args(&[self.old_ret_ty.into()]); let (variant_idx, operands) = if is_return { (ZERO, IndexVec::from_raw(vec![val])) // Poll::Ready(val) @@ -292,7 +292,7 @@ impl<'tcx> TransformVisitor<'tcx> { make_aggregate_adt(poll_def_id, variant_idx, args, operands) } CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => { - let option_def_id = self.tcx.require_lang_item(LangItem::Option, None); + let option_def_id = self.tcx.require_lang_item(LangItem::Option, source_info.span); let args = self.tcx.mk_args(&[self.old_yield_ty.into()]); let (variant_idx, operands) = if is_return { (ZERO, IndexVec::new()) // None @@ -310,7 +310,10 @@ impl<'tcx> TransformVisitor<'tcx> { span: source_info.span, const_: Const::Unevaluated( UnevaluatedConst::new( - self.tcx.require_lang_item(LangItem::AsyncGenFinished, None), + self.tcx.require_lang_item( + LangItem::AsyncGenFinished, + source_info.span, + ), self.tcx.mk_args(&[yield_ty.into()]), ), self.old_yield_ty, @@ -323,7 +326,7 @@ impl<'tcx> TransformVisitor<'tcx> { } CoroutineKind::Coroutine(_) => { let coroutine_state_def_id = - self.tcx.require_lang_item(LangItem::CoroutineState, None); + self.tcx.require_lang_item(LangItem::CoroutineState, source_info.span); let args = self.tcx.mk_args(&[self.old_yield_ty.into(), self.old_ret_ty.into()]); let variant_idx = if is_return { ONE // CoroutineState::Complete(val) @@ -496,7 +499,7 @@ fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Bo fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let ref_coroutine_ty = body.local_decls.raw[1].ty; - let pin_did = tcx.require_lang_item(LangItem::Pin, Some(body.span)); + let pin_did = tcx.require_lang_item(LangItem::Pin, body.span); let pin_adt_ref = tcx.adt_def(pin_did); let args = tcx.mk_args(&[ref_coroutine_ty.into()]); let pin_ref_coroutine_ty = Ty::new_adt(tcx, pin_adt_ref, args); @@ -557,7 +560,7 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> Ty // replace the type of the `resume` argument replace_resume_ty_local(tcx, body, CTX_ARG, context_mut_ref); - let get_context_def_id = tcx.require_lang_item(LangItem::GetContext, None); + let get_context_def_id = tcx.require_lang_item(LangItem::GetContext, body.span); for bb in body.basic_blocks.indices() { let bb_data = &body[bb]; @@ -618,7 +621,7 @@ fn replace_resume_ty_local<'tcx>( #[cfg(debug_assertions)] { if let ty::Adt(resume_ty_adt, _) = local_ty.kind() { - let expected_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None)); + let expected_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, body.span)); assert_eq!(*resume_ty_adt, expected_adt); } else { panic!("expected `ResumeTy`, found `{:?}`", local_ty); @@ -1095,7 +1098,7 @@ fn insert_term_block<'tcx>(body: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) -> fn return_poll_ready_assign<'tcx>(tcx: TyCtxt<'tcx>, source_info: SourceInfo) -> Statement<'tcx> { // Poll::Ready(()) - let poll_def_id = tcx.require_lang_item(LangItem::Poll, None); + let poll_def_id = tcx.require_lang_item(LangItem::Poll, source_info.span); let args = tcx.mk_args(&[tcx.types.unit.into()]); let val = Operand::Constant(Box::new(ConstOperand { span: source_info.span, @@ -1437,7 +1440,7 @@ fn check_field_tys_sized<'tcx>( ), param_env, field_ty.ty, - tcx.require_lang_item(hir::LangItem::Sized, Some(field_ty.source_info.span)), + tcx.require_lang_item(hir::LangItem::Sized, field_ty.source_info.span), ); } @@ -1473,14 +1476,14 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { let new_ret_ty = match coroutine_kind { CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => { // Compute Poll<return_ty> - let poll_did = tcx.require_lang_item(LangItem::Poll, None); + let poll_did = tcx.require_lang_item(LangItem::Poll, body.span); let poll_adt_ref = tcx.adt_def(poll_did); let poll_args = tcx.mk_args(&[old_ret_ty.into()]); Ty::new_adt(tcx, poll_adt_ref, poll_args) } CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => { // Compute Option<yield_ty> - let option_did = tcx.require_lang_item(LangItem::Option, None); + let option_did = tcx.require_lang_item(LangItem::Option, body.span); let option_adt_ref = tcx.adt_def(option_did); let option_args = tcx.mk_args(&[old_yield_ty.into()]); Ty::new_adt(tcx, option_adt_ref, option_args) @@ -1491,7 +1494,7 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { } CoroutineKind::Coroutine(_) => { // Compute CoroutineState<yield_ty, return_ty> - let state_did = tcx.require_lang_item(LangItem::CoroutineState, None); + let state_did = tcx.require_lang_item(LangItem::CoroutineState, body.span); let state_adt_ref = tcx.adt_def(state_did); let state_args = tcx.mk_args(&[old_yield_ty.into(), old_ret_ty.into()]); Ty::new_adt(tcx, state_adt_ref, state_args) diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index 625e53f9959..6021e795d21 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -42,7 +42,7 @@ fn build_poll_call<'tcx>( context_ref_place: &Place<'tcx>, unwind: UnwindAction, ) -> BasicBlock { - let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, None); + let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, DUMMY_SP); let poll_fn = Ty::new_fn_def(tcx, poll_fn, [fut_ty]); let poll_fn = Operand::Constant(Box::new(ConstOperand { span: DUMMY_SP, @@ -77,11 +77,8 @@ fn build_pin_fut<'tcx>( let fut_ty = fut_place.ty(&body.local_decls, tcx).ty; let fut_ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, fut_ty); let fut_ref_place = Place::from(body.local_decls.push(LocalDecl::new(fut_ref_ty, span))); - let pin_fut_new_unchecked_fn = Ty::new_fn_def( - tcx, - tcx.require_lang_item(LangItem::PinNewUnchecked, Some(span)), - [fut_ref_ty], - ); + let pin_fut_new_unchecked_fn = + Ty::new_fn_def(tcx, tcx.require_lang_item(LangItem::PinNewUnchecked, span), [fut_ref_ty]); let fut_pin_ty = pin_fut_new_unchecked_fn.fn_sig(tcx).output().skip_binder(); let fut_pin_place = Place::from(body.local_decls.push(LocalDecl::new(fut_pin_ty, span))); let pin_fut_new_unchecked_fn = Operand::Constant(Box::new(ConstOperand { @@ -143,13 +140,15 @@ fn build_poll_switch<'tcx>( let Discr { val: poll_ready_discr, ty: poll_discr_ty } = poll_enum .discriminant_for_variant( tcx, - poll_enum_adt.variant_index_with_id(tcx.require_lang_item(LangItem::PollReady, None)), + poll_enum_adt + .variant_index_with_id(tcx.require_lang_item(LangItem::PollReady, DUMMY_SP)), ) .unwrap(); let poll_pending_discr = poll_enum .discriminant_for_variant( tcx, - poll_enum_adt.variant_index_with_id(tcx.require_lang_item(LangItem::PollPending, None)), + poll_enum_adt + .variant_index_with_id(tcx.require_lang_item(LangItem::PollPending, DUMMY_SP)), ) .unwrap() .val; @@ -316,16 +315,17 @@ pub(super) fn expand_async_drops<'tcx>( // pending => return rv (yield) // ready => *continue_bb|drop_bb* + let source_info = body[bb].terminator.as_ref().unwrap().source_info; + // Compute Poll<> (aka Poll with void return) - let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None)); + let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, source_info.span)); let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()])); - let poll_decl = LocalDecl::new(poll_enum, body.span); + let poll_decl = LocalDecl::new(poll_enum, source_info.span); let poll_unit_place = Place::from(body.local_decls.push(poll_decl)); // First state-loop yield for mainline let context_ref_place = - Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, body.span))); - let source_info = body[bb].terminator.as_ref().unwrap().source_info; + Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, source_info.span))); let arg = Rvalue::Use(Operand::Move(Place::from(CTX_ARG))); body[bb].statements.push(Statement { source_info, @@ -353,8 +353,9 @@ pub(super) fn expand_async_drops<'tcx>( let mut dropline_context_ref: Option<Place<'_>> = None; let mut dropline_call_bb: Option<BasicBlock> = None; if !is_dropline_bb { - let context_ref_place2: Place<'_> = - Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, body.span))); + let context_ref_place2: Place<'_> = Place::from( + body.local_decls.push(LocalDecl::new(context_mut_ref, source_info.span)), + ); let drop_yield_block = insert_term_block(body, TerminatorKind::Unreachable); // `kind` replaced later to yield let drop_switch_block = build_poll_switch( tcx, @@ -394,7 +395,7 @@ pub(super) fn expand_async_drops<'tcx>( span: source_info.span, const_: Const::Unevaluated( UnevaluatedConst::new( - tcx.require_lang_item(LangItem::AsyncGenPending, None), + tcx.require_lang_item(LangItem::AsyncGenPending, source_info.span), tcx.mk_args(&[yield_ty.into()]), ), full_yield_ty, @@ -404,7 +405,7 @@ pub(super) fn expand_async_drops<'tcx>( } else { // value needed only for return-yields or gen-coroutines, so just const here Operand::Constant(Box::new(ConstOperand { - span: body.span, + span: source_info.span, user_ty: None, const_: Const::from_bool(tcx, false), })) @@ -595,7 +596,7 @@ pub(super) fn create_coroutine_drop_shim<'tcx>( // Update the body's def to become the drop glue. let coroutine_instance = body.source.instance; - let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, None); + let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, body.span); let drop_instance = InstanceKind::DropGlue(drop_in_place, Some(coroutine_ty)); // Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible @@ -666,7 +667,7 @@ pub(super) fn create_coroutine_drop_shim_async<'tcx>( } // Replace the return variable: Poll<RetT> to Poll<()> - let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None)); + let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, body.span)); let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()])); body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(poll_enum, source_info); @@ -717,7 +718,7 @@ pub(super) fn create_coroutine_drop_shim_proxy_async<'tcx>( let source_info = SourceInfo::outermost(body.span); // Replace the return variable: Poll<RetT> to Poll<()> - let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None)); + let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, body.span)); let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()])); body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(poll_enum, source_info); diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index c15d7d6f732..3a5e2620b14 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -235,11 +235,8 @@ where let (fut_ty, drop_fn_def_id, trait_args) = if call_destructor_only { // Resolving obj.<AsyncDrop::drop>() - let trait_ref = ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::AsyncDrop, Some(span)), - [drop_ty], - ); + let trait_ref = + ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::AsyncDrop, span), [drop_ty]); let (drop_trait, trait_args) = match tcx.codegen_select_candidate( ty::TypingEnv::fully_monomorphized().as_query_input(trait_ref), ) { @@ -292,7 +289,7 @@ where (sig.output(), drop_fn_def_id, trait_args) } else { // Resolving async_drop_in_place<T> function for drop_ty - let drop_fn_def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, Some(span)); + let drop_fn_def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, span); let trait_args = tcx.mk_args(&[drop_ty.into()]); let sig = tcx.fn_sig(drop_fn_def_id).instantiate(tcx, trait_args); let sig = tcx.instantiate_bound_regions_with_erased(sig); @@ -319,7 +316,7 @@ where // pin_obj_place preparation let pin_obj_new_unchecked_fn = Ty::new_fn_def( tcx, - tcx.require_lang_item(LangItem::PinNewUnchecked, Some(span)), + tcx.require_lang_item(LangItem::PinNewUnchecked, span), [GenericArg::from(obj_ref_ty)], ); let pin_obj_ty = pin_obj_new_unchecked_fn.fn_sig(tcx).output().no_bound_vars().unwrap(); @@ -937,7 +934,7 @@ where fn destructor_call_block_sync(&mut self, (succ, unwind): (BasicBlock, Unwind)) -> BasicBlock { debug!("destructor_call_block_sync({:?}, {:?})", self, succ); let tcx = self.tcx(); - let drop_trait = tcx.require_lang_item(LangItem::Drop, None); + let drop_trait = tcx.require_lang_item(LangItem::Drop, DUMMY_SP); let drop_fn = tcx.associated_item_def_ids(drop_trait)[0]; let ty = self.place_ty(self.place); diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 9688ac8ed2e..6d45bbc6e16 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -98,7 +98,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< build_call_shim(tcx, instance, None, CallKind::Direct(def_id)) } ty::InstanceKind::ClosureOnceShim { call_once: _, track_caller: _ } => { - let fn_mut = tcx.require_lang_item(LangItem::FnMut, None); + let fn_mut = tcx.require_lang_item(LangItem::FnMut, DUMMY_SP); let call_mut = tcx .associated_items(fn_mut) .in_definition_order() diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index fbc8ee9b06c..fd7b7362cd9 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -64,7 +64,7 @@ pub(super) fn build_async_drop_shim<'tcx>( let needs_async_drop = drop_ty.needs_async_drop(tcx, typing_env); let needs_sync_drop = !needs_async_drop && drop_ty.needs_drop(tcx, typing_env); - let resume_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None)); + let resume_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, DUMMY_SP)); let resume_ty = Ty::new_adt(tcx, resume_adt, ty::List::empty()); let fn_sig = ty::Binder::dummy(tcx.mk_fn_sig( @@ -220,7 +220,7 @@ fn build_adrop_for_coroutine_shim<'tcx>( body.source.instance = instance; body.phase = MirPhase::Runtime(RuntimePhase::Initial); body.var_debug_info.clear(); - let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, Some(span))); + let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, span)); let args = tcx.mk_args(&[proxy_ref.into()]); let pin_proxy_ref = Ty::new_adt(tcx, pin_adt_ref, args); @@ -308,10 +308,10 @@ fn build_adrop_for_adrop_shim<'tcx>( let cor_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, impl_ty); // ret_ty = `Poll<()>` - let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None)); + let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, span)); let ret_ty = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()])); // env_ty = `Pin<&mut proxy_ty>` - let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, None)); + let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, span)); let env_ty = Ty::new_adt(tcx, pin_adt_ref, tcx.mk_args(&[proxy_ref.into()])); // sig = `fn (Pin<&mut proxy_ty>, &mut Context) -> Poll<()>` let sig = tcx.mk_fn_sig( @@ -376,7 +376,7 @@ fn build_adrop_for_adrop_shim<'tcx>( let cor_pin_ty = Ty::new_adt(tcx, pin_adt_ref, tcx.mk_args(&[cor_ref.into()])); let cor_pin_place = Place::from(locals.push(LocalDecl::new(cor_pin_ty, span))); - let pin_fn = tcx.require_lang_item(LangItem::PinNewUnchecked, Some(span)); + let pin_fn = tcx.require_lang_item(LangItem::PinNewUnchecked, span); // call Pin<FutTy>::new_unchecked(&mut impl_cor) blocks.push(BasicBlockData { statements, @@ -396,7 +396,7 @@ fn build_adrop_for_adrop_shim<'tcx>( }); // When dropping async drop coroutine, we continue its execution: // we call impl::poll (impl_layout, ctx) - let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, None); + let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, span); let resume_ctx = Place::from(Local::new(2)); blocks.push(BasicBlockData { statements: vec![], diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index c8aa7588d03..fd91508cc11 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -1253,7 +1253,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.tcx, self.tcx.require_lang_item( LangItem::CoerceUnsized, - Some(self.body.source_info(location).span), + self.body.source_info(location).span, ), [op_ty, *target_type], )) { diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 1ee977a5457..173030e0326 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -781,7 +781,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { let tcx = self.tcx; let push_mono_lang_item = |this: &mut Self, lang_item: LangItem| { - let instance = Instance::mono(tcx, tcx.require_lang_item(lang_item, Some(source))); + let instance = Instance::mono(tcx, tcx.require_lang_item(lang_item, source)); if tcx.should_codegen_locally(instance) { this.used_items.push(create_fn_mono_item(tcx, instance, source)); } @@ -921,7 +921,7 @@ fn visit_instance_use<'tcx>( // be lowered in codegen to nothing or a call to panic_nounwind. So if we encounter any // of those intrinsics, we need to include a mono item for panic_nounwind, else we may try to // codegen a call to that function without generating code for the function itself. - let def_id = tcx.require_lang_item(LangItem::PanicNounwind, None); + let def_id = tcx.require_lang_item(LangItem::PanicNounwind, source); let panic_instance = Instance::mono(tcx, def_id); if tcx.should_codegen_locally(panic_instance) { output.push(create_fn_mono_item(tcx, panic_instance, source)); diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 5c66017bc61..05683940cba 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -29,7 +29,7 @@ fn custom_coerce_unsize_info<'tcx>( ) -> Result<CustomCoerceUnsized, ErrorGuaranteed> { let trait_ref = ty::TraitRef::new( tcx.tcx, - tcx.require_lang_item(LangItem::CoerceUnsized, Some(tcx.span)), + tcx.require_lang_item(LangItem::CoerceUnsized, tcx.span), [source_ty, target_ty], ); diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 17481731b11..6eaec2e29ad 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -7,6 +7,7 @@ use rustc_ast::{ Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind, UnsafeBinderTy, }; +use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{Applicability, Diag, PResult}; use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym}; use thin_vec::{ThinVec, thin_vec}; @@ -104,14 +105,17 @@ fn can_begin_dyn_bound_in_edition_2015(t: &Token) -> bool { impl<'a> Parser<'a> { /// Parses a type. pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> { - self.parse_ty_common( - AllowPlus::Yes, - AllowCVariadic::No, - RecoverQPath::Yes, - RecoverReturnSign::Yes, - None, - RecoverQuestionMark::Yes, - ) + // Make sure deeply nested types don't overflow the stack. + ensure_sufficient_stack(|| { + self.parse_ty_common( + AllowPlus::Yes, + AllowCVariadic::No, + RecoverQPath::Yes, + RecoverReturnSign::Yes, + None, + RecoverQuestionMark::Yes, + ) + }) } pub(super) fn parse_ty_with_generics_recovery( diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 2a4be5fc3b1..3dc285fdab6 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1729,7 +1729,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { if ident.name == kw::StaticLifetime { self.record_lifetime_res( lifetime.id, - LifetimeRes::Static { suppress_elision_warning: false }, + LifetimeRes::Static, LifetimeElisionCandidate::Named, ); return; @@ -1877,8 +1877,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { if lifetimes_in_scope.is_empty() { self.record_lifetime_res( lifetime.id, - // We are inside a const item, so do not warn. - LifetimeRes::Static { suppress_elision_warning: true }, + LifetimeRes::Static, elision_candidate, ); return; @@ -2225,47 +2224,6 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { panic!("lifetime {id:?} resolved multiple times ({prev_res:?} before, {res:?} now)") } - match candidate { - LifetimeElisionCandidate::Missing(missing @ MissingLifetime { .. }) => { - debug_assert_eq!(id, missing.id); - match res { - LifetimeRes::Static { suppress_elision_warning } => { - if !suppress_elision_warning { - self.r.lint_buffer.buffer_lint( - lint::builtin::ELIDED_NAMED_LIFETIMES, - missing.id_for_lint, - missing.span, - BuiltinLintDiag::ElidedNamedLifetimes { - elided: (missing.span, missing.kind), - resolution: lint::ElidedLifetimeResolution::Static, - }, - ); - } - } - LifetimeRes::Param { param, binder: _ } => { - let tcx = self.r.tcx(); - self.r.lint_buffer.buffer_lint( - lint::builtin::ELIDED_NAMED_LIFETIMES, - missing.id_for_lint, - missing.span, - BuiltinLintDiag::ElidedNamedLifetimes { - elided: (missing.span, missing.kind), - resolution: lint::ElidedLifetimeResolution::Param( - tcx.item_name(param.into()), - tcx.source_span(param), - ), - }, - ); - } - LifetimeRes::Fresh { .. } - | LifetimeRes::Infer - | LifetimeRes::Error - | LifetimeRes::ElidedAnchor { .. } => {} - } - } - LifetimeElisionCandidate::Ignore | LifetimeElisionCandidate::Named => {} - } - match res { LifetimeRes::Param { .. } | LifetimeRes::Fresh { .. } | LifetimeRes::Static { .. } => { if let Some(ref mut candidates) = self.lifetime_elision_candidates { @@ -2788,14 +2746,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .. }) => { self.with_static_rib(def_kind, |this| { - this.with_lifetime_rib( - LifetimeRibKind::Elided(LifetimeRes::Static { - suppress_elision_warning: true, - }), - |this| { - this.visit_ty(ty); - }, - ); + this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| { + this.visit_ty(ty); + }); if let Some(expr) = expr { // We already forbid generic params because of the above item rib, // so it doesn't matter whether this is a trivial constant. @@ -2832,9 +2785,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { this.visit_generics(generics); this.with_lifetime_rib( - LifetimeRibKind::Elided(LifetimeRes::Static { - suppress_elision_warning: true, - }), + LifetimeRibKind::Elided(LifetimeRes::Static), |this| this.visit_ty(ty), ); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 97a45fcf233..2f6aed35f25 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3440,7 +3440,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { maybe_static = true; in_scope_lifetimes = vec![( Ident::with_dummy_span(kw::StaticLifetime), - (DUMMY_NODE_ID, LifetimeRes::Static { suppress_elision_warning: false }), + (DUMMY_NODE_ID, LifetimeRes::Static), )]; } } else if elided_len == 0 { @@ -3452,7 +3452,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { maybe_static = true; in_scope_lifetimes = vec![( Ident::with_dummy_span(kw::StaticLifetime), - (DUMMY_NODE_ID, LifetimeRes::Static { suppress_elision_warning: false }), + (DUMMY_NODE_ID, LifetimeRes::Static), )]; } } else if num_params == 1 { diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index d2917478e4e..c69991f3fb2 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -14,7 +14,7 @@ use rustc_middle::ty::{ TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UintTy, }; use rustc_span::def_id::DefId; -use rustc_span::sym; +use rustc_span::{DUMMY_SP, sym}; use rustc_trait_selection::traits; use tracing::{debug, instrument}; @@ -414,7 +414,7 @@ pub(crate) fn transform_instance<'tcx>( } ty::Coroutine(..) => match tcx.coroutine_kind(instance.def_id()).unwrap() { hir::CoroutineKind::Coroutine(..) => ( - tcx.require_lang_item(LangItem::Coroutine, None), + tcx.require_lang_item(LangItem::Coroutine, DUMMY_SP), Some(instance.args.as_coroutine().resume_ty()), ), hir::CoroutineKind::Desugared(desugaring, _) => { @@ -423,11 +423,11 @@ pub(crate) fn transform_instance<'tcx>( hir::CoroutineDesugaring::AsyncGen => LangItem::AsyncIterator, hir::CoroutineDesugaring::Gen => LangItem::Iterator, }; - (tcx.require_lang_item(lang_item, None), None) + (tcx.require_lang_item(lang_item, DUMMY_SP), None) } }, ty::CoroutineClosure(..) => ( - tcx.require_lang_item(LangItem::FnOnce, None), + tcx.require_lang_item(LangItem::FnOnce, DUMMY_SP), Some( tcx.instantiate_bound_regions_with_erased( instance.args.as_coroutine_closure().coroutine_closure_sig(), diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 8e2137da655..2c16672d786 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -73,7 +73,7 @@ use rustc_middle::ty::{ TypeVisitableExt, }; use rustc_span::def_id::LOCAL_CRATE; -use rustc_span::{BytePos, DesugaringKind, Pos, Span, sym}; +use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Pos, Span, sym}; use tracing::{debug, instrument}; use crate::error_reporting::TypeErrCtxt; @@ -194,7 +194,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { _ => return None, }; - let future_trait = self.tcx.require_lang_item(LangItem::Future, None); + let future_trait = self.tcx.require_lang_item(LangItem::Future, DUMMY_SP); let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0]; self.tcx diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs index d8b405e904c..8a67e4ccd45 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs @@ -6,7 +6,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::{LangItem, lang_items}; use rustc_middle::ty::{AssocItemContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv}; -use rustc_span::{DesugaringKind, Ident, Span, sym}; +use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, sym}; use tracing::debug; use crate::traits::specialization_graph; @@ -31,9 +31,9 @@ impl CallDesugaringKind { pub fn trait_def_id(self, tcx: TyCtxt<'_>) -> DefId { match self { Self::ForLoopIntoIter => tcx.get_diagnostic_item(sym::IntoIterator).unwrap(), - Self::ForLoopNext => tcx.require_lang_item(LangItem::Iterator, None), + Self::ForLoopNext => tcx.require_lang_item(LangItem::Iterator, DUMMY_SP), Self::QuestionBranch | Self::TryBlockFromOutput => { - tcx.require_lang_item(LangItem::Try, None) + tcx.require_lang_item(LangItem::Try, DUMMY_SP) } Self::QuestionFromResidual => tcx.get_diagnostic_item(sym::FromResidual).unwrap(), Self::Await => tcx.get_diagnostic_item(sym::IntoFuture).unwrap(), diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 9c301373cf9..3b7fd8b7a20 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -955,7 +955,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { return false; }; - let clone_trait = self.tcx.require_lang_item(LangItem::Clone, None); + let clone_trait = self.tcx.require_lang_item(LangItem::Clone, obligation.cause.span); let has_clone = |ty| { self.type_implements_trait(clone_trait, [ty], obligation.param_env) .must_apply_modulo_regions() @@ -3625,7 +3625,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { trait_pred: ty::PolyTraitPredicate<'tcx>, span: Span, ) { - let future_trait = self.tcx.require_lang_item(LangItem::Future, None); + let future_trait = self.tcx.require_lang_item(LangItem::Future, span); let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty()); let impls_future = self.type_implements_trait( @@ -4141,7 +4141,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let pred = ty::Binder::dummy(ty::TraitPredicate { trait_ref: ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Clone, Some(span)), + tcx.require_lang_item(LangItem::Clone, span), [*ty], ), polarity: ty::PredicatePolarity::Positive, diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 0bea308ed5c..06f81ac554e 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -593,7 +593,7 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> { matches!( arg, hir::GenericArg::Lifetime(lifetime) - if lifetime.is_syntactically_hidden() + if lifetime.is_implicit() ) }) { self.suggestions.push(( diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 0dab3adadb0..0118321befb 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -38,7 +38,7 @@ impl<'tcx> InferCtxt<'tcx> { return self.tcx.type_is_copy_modulo_regions(self.typing_env(param_env), ty); } - let copy_def_id = self.tcx.require_lang_item(LangItem::Copy, None); + let copy_def_id = self.tcx.require_lang_item(LangItem::Copy, DUMMY_SP); // This can get called from typeck (by euv), and `moves_by_default` // rightly refuses to work with inference variables, but @@ -49,7 +49,7 @@ impl<'tcx> InferCtxt<'tcx> { fn type_is_clone_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { let ty = self.resolve_vars_if_possible(ty); - let clone_def_id = self.tcx.require_lang_item(LangItem::Clone, None); + let clone_def_id = self.tcx.require_lang_item(LangItem::Clone, DUMMY_SP); traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, clone_def_id) } @@ -59,12 +59,12 @@ impl<'tcx> InferCtxt<'tcx> { ty: Ty<'tcx>, ) -> bool { let ty = self.resolve_vars_if_possible(ty); - let use_cloned_def_id = self.tcx.require_lang_item(LangItem::UseCloned, None); + let use_cloned_def_id = self.tcx.require_lang_item(LangItem::UseCloned, DUMMY_SP); traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, use_cloned_def_id) } fn type_is_sized_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { - let lang_item = self.tcx.require_lang_item(LangItem::Sized, None); + let lang_item = self.tcx.require_lang_item(LangItem::Sized, DUMMY_SP); traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, lang_item) } diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index cc5861b5a1f..e77d9e32cb9 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -248,7 +248,7 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>( obligation: &HostEffectObligation<'tcx>, ) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> { let tcx = selcx.tcx(); - let destruct_def_id = tcx.require_lang_item(LangItem::Destruct, None); + let destruct_def_id = tcx.require_lang_item(LangItem::Destruct, obligation.cause.span); let self_ty = obligation.predicate.self_ty(); let const_conditions = match *self_ty.kind() { @@ -267,7 +267,7 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>( Some(hir::Constness::NotConst) => return Err(EvaluationFailure::NoSolution), // `Drop` impl exists, and it's const. Require `Ty: ~const Drop` to hold. Some(hir::Constness::Const) => { - let drop_def_id = tcx.require_lang_item(LangItem::Drop, None); + let drop_def_id = tcx.require_lang_item(LangItem::Drop, obligation.cause.span); let drop_trait_ref = ty::TraitRef::new(tcx, drop_def_id, [self_ty]); const_conditions.push(drop_trait_ref); } diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index a4b6f330b9d..393f458bea2 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -157,7 +157,7 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>( parent_cause.clone(), param_env, inner_ty, - tcx.require_lang_item(lang_item, Some(parent_cause.span)), + tcx.require_lang_item(lang_item, parent_cause.span), ); let errors = ocx.select_all_or_error(); @@ -193,7 +193,7 @@ pub fn all_fields_implement_trait<'tcx>( parent_cause: ObligationCause<'tcx>, lang_item: LangItem, ) -> Result<(), Vec<(&'tcx ty::FieldDef, Ty<'tcx>, InfringingFieldsReason<'tcx>)>> { - let trait_def_id = tcx.require_lang_item(lang_item, Some(parent_cause.span)); + let trait_def_id = tcx.require_lang_item(lang_item, parent_cause.span); let mut infringing = Vec::new(); for variant in adt.variants() { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index ed0f34b5aa9..6dd80551980 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1117,7 +1117,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( selcx.tcx(), selcx.tcx().require_lang_item( LangItem::Sized, - Some(obligation.cause.span), + obligation.cause.span, ), [self_ty], ), @@ -1317,7 +1317,7 @@ fn confirm_coroutine_candidate<'cx, 'tcx>( let tcx = selcx.tcx(); - let coroutine_def_id = tcx.require_lang_item(LangItem::Coroutine, None); + let coroutine_def_id = tcx.require_lang_item(LangItem::Coroutine, obligation.cause.span); let (trait_ref, yield_ty, return_ty) = super::util::coroutine_trait_ref_and_outputs( tcx, @@ -1375,7 +1375,7 @@ fn confirm_future_candidate<'cx, 'tcx>( debug!(?obligation, ?coroutine_sig, ?obligations, "confirm_future_candidate"); let tcx = selcx.tcx(); - let fut_def_id = tcx.require_lang_item(LangItem::Future, None); + let fut_def_id = tcx.require_lang_item(LangItem::Future, obligation.cause.span); let (trait_ref, return_ty) = super::util::future_trait_ref_and_outputs( tcx, @@ -1421,7 +1421,7 @@ fn confirm_iterator_candidate<'cx, 'tcx>( debug!(?obligation, ?gen_sig, ?obligations, "confirm_iterator_candidate"); let tcx = selcx.tcx(); - let iter_def_id = tcx.require_lang_item(LangItem::Iterator, None); + let iter_def_id = tcx.require_lang_item(LangItem::Iterator, obligation.cause.span); let (trait_ref, yield_ty) = super::util::iterator_trait_ref_and_outputs( tcx, @@ -1467,7 +1467,7 @@ fn confirm_async_iterator_candidate<'cx, 'tcx>( debug!(?obligation, ?gen_sig, ?obligations, "confirm_async_iterator_candidate"); let tcx = selcx.tcx(); - let iter_def_id = tcx.require_lang_item(LangItem::AsyncIterator, None); + let iter_def_id = tcx.require_lang_item(LangItem::AsyncIterator, obligation.cause.span); let (trait_ref, yield_ty) = super::util::async_iterator_trait_ref_and_outputs( tcx, @@ -1511,12 +1511,13 @@ fn confirm_builtin_candidate<'cx, 'tcx>( let trait_def_id = tcx.trait_of_item(item_def_id).unwrap(); let args = tcx.mk_args(&[self_ty.into()]); let (term, obligations) = if tcx.is_lang_item(trait_def_id, LangItem::DiscriminantKind) { - let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None); + let discriminant_def_id = + tcx.require_lang_item(LangItem::Discriminant, obligation.cause.span); assert_eq!(discriminant_def_id, item_def_id); (self_ty.discriminant_ty(tcx).into(), PredicateObligations::new()) } else if tcx.is_lang_item(trait_def_id, LangItem::PointeeTrait) { - let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); + let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, obligation.cause.span); assert_eq!(metadata_def_id, item_def_id); let mut obligations = PredicateObligations::new(); @@ -1538,7 +1539,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>( // exist. Instead, `Pointee<Metadata = ()>` should be a supertrait of `Sized`. let sized_predicate = ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Sized, Some(obligation.cause.span)), + tcx.require_lang_item(LangItem::Sized, obligation.cause.span), [self_ty], ); obligations.push(obligation.with(tcx, sized_predicate)); @@ -1620,7 +1621,7 @@ fn confirm_closure_candidate<'cx, 'tcx>( ) } else { let upvars_projection_def_id = - tcx.require_lang_item(LangItem::AsyncFnKindUpvars, None); + tcx.require_lang_item(LangItem::AsyncFnKindUpvars, obligation.cause.span); let tupled_upvars_ty = Ty::new_projection( tcx, upvars_projection_def_id, @@ -1681,8 +1682,9 @@ fn confirm_callable_candidate<'cx, 'tcx>( debug!(?obligation, ?fn_sig, "confirm_callable_candidate"); - let fn_once_def_id = tcx.require_lang_item(LangItem::FnOnce, None); - let fn_once_output_def_id = tcx.require_lang_item(LangItem::FnOnceOutput, None); + let fn_once_def_id = tcx.require_lang_item(LangItem::FnOnce, obligation.cause.span); + let fn_once_output_def_id = + tcx.require_lang_item(LangItem::FnOnceOutput, obligation.cause.span); let predicate = super::util::closure_trait_ref_and_return_type( tcx, @@ -1740,8 +1742,8 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( args.coroutine_captures_by_ref_ty(), ) } else { - let upvars_projection_def_id = - tcx.require_lang_item(LangItem::AsyncFnKindUpvars, None); + let upvars_projection_def_id = tcx + .require_lang_item(LangItem::AsyncFnKindUpvars, obligation.cause.span); // When we don't know the closure kind (and therefore also the closure's upvars, // which are computed at the same time), we must delay the computation of the // generator's upvars. We do this using the `AsyncFnKindHelper`, which as a trait @@ -1798,7 +1800,8 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( let term = match item_name { sym::CallOnceFuture | sym::CallRefFuture => sig.output(), sym::Output => { - let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None); + let future_output_def_id = + tcx.require_lang_item(LangItem::FutureOutput, obligation.cause.span); Ty::new_projection(tcx, future_output_def_id, [sig.output()]) } name => bug!("no such associated type: {name}"), @@ -1831,7 +1834,8 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( let term = match item_name { sym::CallOnceFuture | sym::CallRefFuture => sig.output(), sym::Output => { - let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None); + let future_output_def_id = + tcx.require_lang_item(LangItem::FutureOutput, obligation.cause.span); Ty::new_projection(tcx, future_output_def_id, [sig.output()]) } name => bug!("no such associated type: {name}"), diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index c9169127e0b..7acf0f990d1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -318,7 +318,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let make_freeze_obl = |ty| { let trait_ref = ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Freeze, None), + tcx.require_lang_item(LangItem::Freeze, obligation.cause.span), [ty::GenericArg::from(ty)], ); Obligation::with_depth( @@ -657,7 +657,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); let tr = ty::TraitRef::new( self.tcx(), - self.tcx().require_lang_item(LangItem::Sized, Some(cause.span)), + self.tcx().require_lang_item(LangItem::Sized, cause.span), [output_ty], ); nested.push(Obligation::new(self.infcx.tcx, cause, obligation.param_env, tr)); @@ -877,14 +877,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }); // We must additionally check that the return type impls `Future + Sized`. - let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None); + let future_trait_def_id = + tcx.require_lang_item(LangItem::Future, obligation.cause.span); nested.push(obligation.with( tcx, sig.output().map_bound(|output_ty| { ty::TraitRef::new(tcx, future_trait_def_id, [output_ty]) }), )); - let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None); + let sized_trait_def_id = + tcx.require_lang_item(LangItem::Sized, obligation.cause.span); nested.push(obligation.with( tcx, sig.output().map_bound(|output_ty| { @@ -906,13 +908,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }); // We must additionally check that the return type impls `Future + Sized`. - let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None); + let future_trait_def_id = + tcx.require_lang_item(LangItem::Future, obligation.cause.span); let placeholder_output_ty = self.infcx.enter_forall_and_leak_universe(sig.output()); nested.push(obligation.with( tcx, ty::TraitRef::new(tcx, future_trait_def_id, [placeholder_output_ty]), )); - let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None); + let sized_trait_def_id = + tcx.require_lang_item(LangItem::Sized, obligation.cause.span); nested.push(obligation.with( tcx, sig.output().map_bound(|output_ty| { @@ -946,10 +950,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.param_env, ty::TraitRef::new( self.tcx(), - self.tcx().require_lang_item( - LangItem::AsyncFnKindHelper, - Some(obligation.cause.span), - ), + self.tcx() + .require_lang_item(LangItem::AsyncFnKindHelper, obligation.cause.span), [kind_ty, Ty::from_closure_kind(self.tcx(), goal_kind)], ), )); @@ -1165,7 +1167,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // We can only make objects from sized types. let tr = ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Sized, Some(obligation.cause.span)), + tcx.require_lang_item(LangItem::Sized, obligation.cause.span), [source], ); nested.push(predicate_to_obligation(tr.upcast(tcx))); @@ -1359,7 +1361,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self_ty.map_bound(|ty| { ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Copy, Some(obligation.cause.span)), + tcx.require_lang_item(LangItem::Copy, obligation.cause.span), [ty], ) }), @@ -1411,7 +1413,7 @@ fn pointer_like_goal_for_rpitit<'tcx>( ty::Binder::bind_with_vars( ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::PointerLike, Some(cause.span)), + tcx.require_lang_item(LangItem::PointerLike, cause.span), [Ty::new_projection_from_args(tcx, rpitit_item, args)], ), tcx.mk_bound_variable_kinds(&bound_vars), diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 3018dad8e09..416865e861e 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -541,7 +541,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { let cause = self.cause(cause); let trait_ref = ty::TraitRef::new( self.tcx(), - self.tcx().require_lang_item(LangItem::Sized, Some(cause.span)), + self.tcx().require_lang_item(LangItem::Sized, cause.span), [subty], ); self.out.push(traits::Obligation::with_depth( @@ -895,7 +895,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> { self.tcx(), self.tcx().require_lang_item( LangItem::BikeshedGuaranteedNoDrop, - Some(self.span), + self.span, ), [ty], ) diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 83d7416b03e..bb5187e4f5c 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -11,6 +11,7 @@ use rustc_middle::ty::layout::{ }; use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt}; use rustc_session::config::OptLevel; +use rustc_span::DUMMY_SP; use rustc_span::def_id::DefId; use rustc_target::callconv::{ AbiMap, ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, FnAbi, PassMode, @@ -124,7 +125,7 @@ fn fn_sig_for_fn_abi<'tcx>( let env_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, ty); - let pin_did = tcx.require_lang_item(LangItem::Pin, None); + let pin_did = tcx.require_lang_item(LangItem::Pin, DUMMY_SP); let pin_adt_ref = tcx.adt_def(pin_did); let pin_args = tcx.mk_args(&[env_ty.into()]); let env_ty = match coroutine_kind { @@ -149,7 +150,7 @@ fn fn_sig_for_fn_abi<'tcx>( // The signature should be `Future::poll(_, &mut Context<'_>) -> Poll<Output>` assert_eq!(sig.yield_ty, tcx.types.unit); - let poll_did = tcx.require_lang_item(LangItem::Poll, None); + let poll_did = tcx.require_lang_item(LangItem::Poll, DUMMY_SP); let poll_adt_ref = tcx.adt_def(poll_did); let poll_args = tcx.mk_args(&[sig.return_ty.into()]); let ret_ty = Ty::new_adt(tcx, poll_adt_ref, poll_args); @@ -160,7 +161,7 @@ fn fn_sig_for_fn_abi<'tcx>( { if let ty::Adt(resume_ty_adt, _) = sig.resume_ty.kind() { let expected_adt = - tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None)); + tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, DUMMY_SP)); assert_eq!(*resume_ty_adt, expected_adt); } else { panic!("expected `ResumeTy`, found `{:?}`", sig.resume_ty); @@ -172,7 +173,7 @@ fn fn_sig_for_fn_abi<'tcx>( } hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _) => { // The signature should be `Iterator::next(_) -> Option<Yield>` - let option_did = tcx.require_lang_item(LangItem::Option, None); + let option_did = tcx.require_lang_item(LangItem::Option, DUMMY_SP); let option_adt_ref = tcx.adt_def(option_did); let option_args = tcx.mk_args(&[sig.yield_ty.into()]); let ret_ty = Ty::new_adt(tcx, option_adt_ref, option_args); @@ -196,7 +197,7 @@ fn fn_sig_for_fn_abi<'tcx>( { if let ty::Adt(resume_ty_adt, _) = sig.resume_ty.kind() { let expected_adt = - tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None)); + tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, DUMMY_SP)); assert_eq!(*resume_ty_adt, expected_adt); } else { panic!("expected `ResumeTy`, found `{:?}`", sig.resume_ty); @@ -208,7 +209,7 @@ fn fn_sig_for_fn_abi<'tcx>( } hir::CoroutineKind::Coroutine(_) => { // The signature should be `Coroutine::resume(_, Resume) -> CoroutineState<Yield, Return>` - let state_did = tcx.require_lang_item(LangItem::CoroutineState, None); + let state_did = tcx.require_lang_item(LangItem::CoroutineState, DUMMY_SP); let state_adt_ref = tcx.adt_def(state_did); let state_args = tcx.mk_args(&[sig.yield_ty.into(), sig.return_ty.into()]); let ret_ty = Ty::new_adt(tcx, state_adt_ref, state_args); diff --git a/compiler/rustc_ty_utils/src/common_traits.rs b/compiler/rustc_ty_utils/src/common_traits.rs index bb2c4172b08..7219f40710e 100644 --- a/compiler/rustc_ty_utils/src/common_traits.rs +++ b/compiler/rustc_ty_utils/src/common_traits.rs @@ -4,6 +4,7 @@ use rustc_hir::lang_items::LangItem; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_span::DUMMY_SP; use rustc_trait_selection::traits; fn is_copy_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { @@ -42,7 +43,7 @@ fn is_item_raw<'tcx>( item: LangItem, ) -> bool { let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(query.typing_env); - let trait_def_id = tcx.require_lang_item(item, None); + let trait_def_id = tcx.require_lang_item(item, DUMMY_SP); traits::type_known_to_meet_bound_modulo_regions(&infcx, param_env, query.value, trait_def_id) } diff --git a/compiler/rustc_ty_utils/src/structural_match.rs b/compiler/rustc_ty_utils/src/structural_match.rs index 0b4efab1d9c..e900264a76c 100644 --- a/compiler/rustc_ty_utils/src/structural_match.rs +++ b/compiler/rustc_ty_utils/src/structural_match.rs @@ -16,8 +16,7 @@ fn has_structural_eq_impl<'tcx>(tcx: TyCtxt<'tcx>, adt_ty: Ty<'tcx>) -> bool { let ocx = ObligationCtxt::new(infcx); // require `#[derive(PartialEq)]` - let structural_peq_def_id = - infcx.tcx.require_lang_item(LangItem::StructuralPeq, Some(cause.span)); + let structural_peq_def_id = infcx.tcx.require_lang_item(LangItem::StructuralPeq, cause.span); ocx.register_bound(cause.clone(), ty::ParamEnv::empty(), adt_ty, structural_peq_def_id); // We deliberately skip *reporting* fulfillment errors (via diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 330aaa25d13..e39fd6b947b 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -104,7 +104,7 @@ fn adt_sized_constraint<'tcx>( // perf hack: if there is a `constraint_ty: Sized` bound, then we know // that the type is sized and do not need to check it on the impl. - let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None); + let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, DUMMY_SP); let predicates = tcx.predicates_of(def.did()).predicates; if predicates.iter().any(|(p, _)| { p.as_trait_clause().is_some_and(|trait_pred| { |
