diff options
90 files changed, 490 insertions, 380 deletions
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index ca704082a3f..fd54a153a16 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,3 +1,4 @@ +<!-- homu-ignore:start --> <!-- If this PR is related to an unstable feature or an otherwise tracked effort, please link to the relevant tracking issue here. If you don't know of a related @@ -7,4 +8,5 @@ This PR will get automatically assigned to a reviewer. In case you would like a specific user to review your work, you can assign it to them by using r? <reviewer name> ---> \ No newline at end of file +--> +<!-- homu-ignore:end --> diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 8200a58f31f..9252bec6e4e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -284,7 +284,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { && let CallKind::FnCall { fn_trait_id, self_ty } = kind && let ty::Param(_) = self_ty.kind() && ty == self_ty - && Some(fn_trait_id) == self.infcx.tcx.lang_items().fn_once_trait() + && self.infcx.tcx.is_lang_item(fn_trait_id, LangItem::FnOnce) { // this is a type parameter `T: FnOnce()`, don't suggest `T: FnOnce() + Clone`. true @@ -708,9 +708,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder() && pred.self_ty() == ty { - if Some(pred.def_id()) == tcx.lang_items().fn_trait() { + if tcx.is_lang_item(pred.def_id(), LangItem::Fn) { return Some(hir::Mutability::Not); - } else if Some(pred.def_id()) == tcx.lang_items().fn_mut_trait() { + } else if tcx.is_lang_item(pred.def_id(), LangItem::FnMut) { return Some(hir::Mutability::Mut); } } @@ -1832,7 +1832,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let hir::ExprKind::MethodCall(..) = ex.kind && let Some(method_def_id) = self.typeck_results.type_dependent_def_id(ex.hir_id) - && self.tcx.lang_items().clone_trait() == Some(self.tcx.parent(method_def_id)) + && self.tcx.is_lang_item(self.tcx.parent(method_def_id), LangItem::Clone) { self.clones.push(ex); } @@ -3159,8 +3159,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let is_format_arguments_item = if let Some(expr_ty) = expr_ty && let ty::Adt(adt, _) = expr_ty.kind() { - self.infcx.tcx.lang_items().get(LangItem::FormatArguments) - == Some(adt.did()) + self.infcx.tcx.is_lang_item(adt.did(), LangItem::FormatArguments) } else { false }; diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 1eb67ea367c..abb0b5afbd8 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -6,9 +6,9 @@ use crate::session_diagnostics::{ }; use rustc_errors::{Applicability, Diag}; use rustc_errors::{DiagCtxt, MultiSpan}; -use rustc_hir as hir; use rustc_hir::def::{CtorKind, Namespace}; use rustc_hir::CoroutineKind; +use rustc_hir::{self as hir, LangItem}; use rustc_index::IndexSlice; use rustc_infer::infer::BoundRegionConversionTime; use rustc_infer::traits::SelectionError; @@ -116,7 +116,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { { if let ty::FnDef(id, _) = *const_.ty().kind() { debug!("add_moved_or_invoked_closure_note: id={:?}", id); - if Some(self.infcx.tcx.parent(id)) == self.infcx.tcx.lang_items().fn_once_trait() { + if self.infcx.tcx.is_lang_item(self.infcx.tcx.parent(id), LangItem::FnOnce) { let closure = match args.first() { Some(Spanned { node: Operand::Copy(place) | Operand::Move(place), .. @@ -767,13 +767,12 @@ impl<'tcx> BorrowedContentSource<'tcx> { ty::FnDef(def_id, args) => { let trait_id = tcx.trait_of_item(def_id)?; - let lang_items = tcx.lang_items(); - if Some(trait_id) == lang_items.deref_trait() - || Some(trait_id) == lang_items.deref_mut_trait() + if tcx.is_lang_item(trait_id, LangItem::Deref) + || tcx.is_lang_item(trait_id, LangItem::DerefMut) { Some(BorrowedContentSource::OverloadedDeref(args.type_at(0))) - } else if Some(trait_id) == lang_items.index_trait() - || Some(trait_id) == lang_items.index_mut_trait() + } else if tcx.is_lang_item(trait_id, LangItem::Index) + || tcx.is_lang_item(trait_id, LangItem::IndexMut) { Some(BorrowedContentSource::OverloadedIndex(args.type_at(0))) } else { @@ -1041,7 +1040,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .unwrap_or_else(|| "value".to_owned()); match kind { CallKind::FnCall { fn_trait_id, self_ty } - if Some(fn_trait_id) == self.infcx.tcx.lang_items().fn_once_trait() => + if self.infcx.tcx.is_lang_item(fn_trait_id, LangItem::FnOnce) => { err.subdiagnostic( self.dcx(), @@ -1268,7 +1267,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let ty = moved_place.ty(self.body, tcx).ty; if let ty::Adt(def, args) = ty.peel_refs().kind() - && Some(def.did()) == tcx.lang_items().pin_type() + && tcx.is_lang_item(def.did(), LangItem::Pin) && let ty::Ref(_, _, hir::Mutability::Mut) = args.type_at(0).kind() && let self_ty = self.infcx.instantiate_binder_with_fresh_vars( fn_call_span, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index fcfb297d50a..d62f87de61a 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -328,7 +328,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { if let Some(annotation_index) = constant.user_ty { if let Err(terr) = self.cx.relate_type_and_user_type( constant.const_.ty(), - ty::Variance::Invariant, + ty::Invariant, &UserTypeProjection { base: annotation_index, projs: vec![] }, locations, ConstraintCategory::Boring, @@ -451,7 +451,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { if let Err(terr) = self.cx.relate_type_and_user_type( ty, - ty::Variance::Invariant, + ty::Invariant, user_ty, Locations::All(*span), ConstraintCategory::TypeAnnotation, @@ -1095,7 +1095,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ) -> Result<(), NoSolution> { // Use this order of parameters because the sup type is usually the // "expected" type in diagnostics. - self.relate_types(sup, ty::Variance::Contravariant, sub, locations, category) + self.relate_types(sup, ty::Contravariant, sub, locations, category) } #[instrument(skip(self, category), level = "debug")] @@ -1106,7 +1106,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { locations: Locations, category: ConstraintCategory<'tcx>, ) -> Result<(), NoSolution> { - self.relate_types(expected, ty::Variance::Invariant, found, locations, category) + self.relate_types(expected, ty::Invariant, found, locations, category) } #[instrument(skip(self), level = "debug")] @@ -1146,7 +1146,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { trace!(?curr_projected_ty); let ty = curr_projected_ty.ty; - self.relate_types(ty, v.xform(ty::Variance::Contravariant), a, locations, category)?; + self.relate_types(ty, v.xform(ty::Contravariant), a, locations, category)?; Ok(()) } @@ -1248,7 +1248,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if let Some(annotation_index) = self.rvalue_user_ty(rv) { if let Err(terr) = self.relate_type_and_user_type( rv_ty, - ty::Variance::Invariant, + ty::Invariant, &UserTypeProjection { base: annotation_index, projs: vec![] }, location.to_locations(), ConstraintCategory::Boring, diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index c531c9b209b..b9a82046e59 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -50,14 +50,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { locations: Locations, category: ConstraintCategory<'tcx>, ) -> Result<(), NoSolution> { - NllTypeRelating::new( - self, - locations, - category, - UniverseInfo::other(), - ty::Variance::Invariant, - ) - .relate(a, b)?; + NllTypeRelating::new(self, locations, category, UniverseInfo::other(), ty::Invariant) + .relate(a, b)?; Ok(()) } } @@ -106,15 +100,15 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> { fn ambient_covariance(&self) -> bool { match self.ambient_variance { - ty::Variance::Covariant | ty::Variance::Invariant => true, - ty::Variance::Contravariant | ty::Variance::Bivariant => false, + ty::Covariant | ty::Invariant => true, + ty::Contravariant | ty::Bivariant => false, } } fn ambient_contravariance(&self) -> bool { match self.ambient_variance { - ty::Variance::Contravariant | ty::Variance::Invariant => true, - ty::Variance::Covariant | ty::Variance::Bivariant => false, + ty::Contravariant | ty::Invariant => true, + ty::Covariant | ty::Bivariant => false, } } @@ -336,11 +330,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx debug!(?self.ambient_variance); // In a bivariant context this always succeeds. - let r = if self.ambient_variance == ty::Variance::Bivariant { - Ok(a) - } else { - self.relate(a, b) - }; + let r = if self.ambient_variance == ty::Bivariant { Ok(a) } else { self.relate(a, b) }; self.ambient_variance = old_ambient_variance; @@ -474,7 +464,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx } match self.ambient_variance { - ty::Variance::Covariant => { + ty::Covariant => { // Covariance, so we want `for<..> A <: for<..> B` -- // therefore we compare any instantiation of A (i.e., A // instantiated with existentials) against every @@ -489,7 +479,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx })?; } - ty::Variance::Contravariant => { + ty::Contravariant => { // Contravariance, so we want `for<..> A :> for<..> B` -- // therefore we compare every instantiation of A (i.e., A // instantiated with universals) against any @@ -504,7 +494,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx })?; } - ty::Variance::Invariant => { + ty::Invariant => { // Invariant, so we want `for<..> A == for<..> B` -- // therefore we want `exists<..> A == for<..> B` and // `exists<..> B == for<..> A`. @@ -525,7 +515,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx })?; } - ty::Variance::Bivariant => {} + ty::Bivariant => {} } Ok(a) @@ -584,23 +574,23 @@ impl<'bccx, 'tcx> PredicateEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx, fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { self.register_predicates([ty::Binder::dummy(match self.ambient_variance { - ty::Variance::Covariant => ty::PredicateKind::AliasRelate( + ty::Covariant => ty::PredicateKind::AliasRelate( a.into(), b.into(), ty::AliasRelationDirection::Subtype, ), // a :> b is b <: a - ty::Variance::Contravariant => ty::PredicateKind::AliasRelate( + ty::Contravariant => ty::PredicateKind::AliasRelate( b.into(), a.into(), ty::AliasRelationDirection::Subtype, ), - ty::Variance::Invariant => ty::PredicateKind::AliasRelate( + ty::Invariant => ty::PredicateKind::AliasRelate( a.into(), b.into(), ty::AliasRelationDirection::Equate, ), - ty::Variance::Bivariant => { + ty::Bivariant => { unreachable!("cannot defer an alias-relate goal with Bivariant variance (yet?)") } })]); diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs index 2de804f5e04..c6b26dd873b 100644 --- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs @@ -4,6 +4,7 @@ use std::fmt::Write; use cranelift_codegen::isa::CallConv; use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; +use rustc_hir::LangItem; use rustc_span::sym; use rustc_target::asm::*; use target_lexicon::BinaryFormat; @@ -927,7 +928,7 @@ fn call_inline_asm<'tcx>( fn asm_clif_type<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option<types::Type> { match ty.kind() { // Adapted from https://github.com/rust-lang/rust/blob/f3c66088610c1b80110297c2d9a8b5f9265b013f/compiler/rustc_hir_analysis/src/check/intrinsicck.rs#L136-L151 - ty::Adt(adt, args) if Some(adt.did()) == fx.tcx.lang_items().maybe_uninit() => { + ty::Adt(adt, args) if fx.tcx.is_lang_item(adt.did(), LangItem::MaybeUninit) => { let fields = &adt.non_enum_variant().fields; let ty = fields[FieldIdx::from_u32(1)].ty(fx.tcx, args); let ty::Adt(ty, args) = ty.kind() else { diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 9e01c59a96f..0818d9425e2 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -1,8 +1,8 @@ //! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations. use rustc_errors::{Diag, ErrorGuaranteed}; -use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir, LangItem}; use rustc_index::bit_set::BitSet; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::ObligationCause; @@ -801,7 +801,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // const-eval. // const-eval of the `begin_panic` fn assumes the argument is `&str` - if Some(callee) == tcx.lang_items().begin_panic_fn() { + if tcx.is_lang_item(callee, LangItem::BeginPanic) { match args[0].node.ty(&self.ccx.body.local_decls, tcx).kind() { ty::Ref(_, ty, _) if ty.is_str() => return, _ => self.check_op(ops::PanicNonStr), @@ -819,7 +819,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } } - if Some(callee) == tcx.lang_items().exchange_malloc_fn() { + if tcx.is_lang_item(callee, LangItem::ExchangeMalloc) { self.check_op(ops::HeapAllocation); return; } diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index feab5b929ac..eb9a83fb9cf 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -218,7 +218,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { } else { let mut sugg = None; - if Some(trait_id) == ccx.tcx.lang_items().eq_trait() { + if ccx.tcx.is_lang_item(trait_id, LangItem::PartialEq) { match (args[0].unpack(), args[1].unpack()) { (GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty)) if self_ty == rhs_ty diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 4f6df857142..d3631e0d723 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -230,7 +230,7 @@ impl<'tcx> CompileTimeInterpCx<'tcx> { let def_id = instance.def_id(); if self.tcx.has_attr(def_id, sym::rustc_const_panic_str) - || Some(def_id) == self.tcx.lang_items().begin_panic_fn() + || self.tcx.is_lang_item(def_id, LangItem::BeginPanic) { let args = self.copy_fn_args(args); // &str or &&str @@ -245,7 +245,7 @@ impl<'tcx> CompileTimeInterpCx<'tcx> { let span = self.find_closest_untracked_caller_location(); let (file, line, col) = self.location_triple_for_span(span); return Err(ConstEvalErrKind::Panic { msg, file, line, col }.into()); - } else if Some(def_id) == self.tcx.lang_items().panic_fmt() { + } 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 new_instance = ty::Instance::expect_resolve( @@ -256,7 +256,7 @@ impl<'tcx> CompileTimeInterpCx<'tcx> { ); return Ok(Some(new_instance)); - } else if Some(def_id) == self.tcx.lang_items().align_offset_fn() { + } else if self.tcx.is_lang_item(def_id, LangItem::AlignOffset) { let args = self.copy_fn_args(args); // For align_offset, we replace the function call if the pointer has no address. match self.align_offset(instance, &args, dest, ret)? { diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index a6eef9f5662..4d0f35618ef 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -112,25 +112,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Shift ops can have an RHS with a different numeric type. if matches!(bin_op, Shl | ShlUnchecked | Shr | ShrUnchecked) { - let size = left.layout.size.bits(); + let l_bits = left.layout.size.bits(); // Compute the equivalent shift modulo `size` that is in the range `0..size`. (This is // the one MIR operator that does *not* directly map to a single LLVM operation.) let (shift_amount, overflow) = if right.layout.abi.is_signed() { let shift_amount = r_signed(); - let overflow = shift_amount < 0 || shift_amount >= i128::from(size); - // Deliberately wrapping `as` casts: shift_amount *can* be negative, but the result - // of the `as` will be equal modulo `size` (since it is a power of two). - let masked_amount = (shift_amount as u128) % u128::from(size); - assert_eq!(overflow, shift_amount != i128::try_from(masked_amount).unwrap()); - (masked_amount, overflow) + let rem = shift_amount.rem_euclid(l_bits.into()); + // `rem` is guaranteed positive, so the `unwrap` cannot fail + (u128::try_from(rem).unwrap(), rem != shift_amount) } else { let shift_amount = r_unsigned(); - let overflow = shift_amount >= u128::from(size); - let masked_amount = shift_amount % u128::from(size); - assert_eq!(overflow, shift_amount != masked_amount); - (masked_amount, overflow) + let rem = shift_amount.rem_euclid(l_bits.into()); + (rem, rem != shift_amount) }; - let shift_amount = u32::try_from(shift_amount).unwrap(); // we masked so this will always fit + let shift_amount = u32::try_from(shift_amount).unwrap(); // we brought this in the range `0..size` so this will always fit // Compute the shifted result. let result = if left.layout.abi.is_signed() { let l = l_signed(); diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 38ecd7dd082..7f0d72b3a8d 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -53,7 +53,7 @@ impl<'tcx> Bounds<'tcx> { span, ); // FIXME(-Znext-solver): We can likely remove this hack once the new trait solver lands. - if tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) { + if tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) { self.clauses.insert(0, clause); } else { self.clauses.push(clause); diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 2672614a895..5e62a5ced19 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -1,6 +1,6 @@ use rustc_ast::InlineAsmTemplatePiece; use rustc_data_structures::fx::FxIndexSet; -use rustc_hir as hir; +use rustc_hir::{self as hir, LangItem}; use rustc_middle::bug; use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; use rustc_session::lint; @@ -134,7 +134,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // `!` is allowed for input but not for output (issue #87802) ty::Never if is_input => return None, _ if ty.references_error() => return None, - ty::Adt(adt, args) if Some(adt.did()) == self.tcx.lang_items().maybe_uninit() => { + ty::Adt(adt, args) if self.tcx.is_lang_item(adt.did(), LangItem::MaybeUninit) => { let fields = &adt.non_enum_variant().fields; let ty = fields[FieldIdx::from_u32(1)].ty(self.tcx, args); // FIXME: Are we just trying to map to the `T` in `MaybeUninit<T>`? diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index eae41d28e89..e9961d3ad08 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -8,6 +8,7 @@ use crate::errors; use rustc_errors::{codes::*, struct_span_code_err}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::LangItem; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_session::parse::feature_err; @@ -49,7 +50,7 @@ fn enforce_trait_manually_implementable( ) -> Result<(), ErrorGuaranteed> { let impl_header_span = tcx.def_span(impl_def_id); - if tcx.lang_items().freeze_trait() == Some(trait_def_id) { + if tcx.is_lang_item(trait_def_id, LangItem::Freeze) { if !tcx.features().freeze_impls { feature_err( &tcx.sess, @@ -75,7 +76,7 @@ fn enforce_trait_manually_implementable( // Maintain explicit error code for `Unsize`, since it has a useful // explanation about using `CoerceUnsized` instead. - if Some(trait_def_id) == tcx.lang_items().unsize_trait() { + if tcx.is_lang_item(trait_def_id, LangItem::Unsize) { err.code(E0328); } diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 3ab319a037b..d6f3f4d640b 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -45,6 +45,7 @@ hir_typeck_convert_using_method = try using `{$sugg}` to convert `{$found}` to ` hir_typeck_ctor_is_private = tuple struct constructor `{$def}` is private hir_typeck_dependency_on_unit_never_type_fallback = this function depends on never type fallback being `()` + .note = in edition 2024, the requirement `{$obligation}` will fail .help = specify the types explicitly hir_typeck_deref_is_empty = this expression `Deref`s to `{$deref_ty}` which implements `is_empty` diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 93222c18686..46c85515575 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -5,9 +5,9 @@ use super::{Expectation, FnCtxt, TupleArgumentsFlag}; use crate::errors; use rustc_ast::util::parser::PREC_POSTFIX; use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey}; -use rustc_hir as hir; use rustc_hir::def::{self, CtorKind, Namespace, Res}; use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir, LangItem}; use rustc_hir_analysis::autoderef::Autoderef; use rustc_infer::traits::ObligationCauseCode; use rustc_infer::{ @@ -41,7 +41,7 @@ pub fn check_legal_trait_for_method_call( trait_id: DefId, body_id: DefId, ) -> Result<(), ErrorGuaranteed> { - if tcx.lang_items().drop_trait() == Some(trait_id) + if tcx.is_lang_item(trait_id, LangItem::Drop) && tcx.lang_items().fallback_surface_drop_fn() != Some(body_id) { let sugg = if let Some(receiver) = receiver.filter(|s| !s.is_empty()) { diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 6dd34024fd1..24f039b8e90 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -7,7 +7,7 @@ use rustc_errors::{ SubdiagMessageOp, Subdiagnostic, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{self, Ty}; use rustc_span::{ edition::{Edition, LATEST_STABLE_EDITION}, symbol::Ident, @@ -186,7 +186,11 @@ pub enum NeverTypeFallbackFlowingIntoUnsafe { #[derive(LintDiagnostic)] #[help] #[diag(hir_typeck_dependency_on_unit_never_type_fallback)] -pub struct DependencyOnUnitNeverTypeFallback {} +pub struct DependencyOnUnitNeverTypeFallback<'tcx> { + #[note] + pub obligation_span: Span, + pub obligation: ty::Predicate<'tcx>, +} #[derive(Subdiagnostic)] #[multipart_suggestion( diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index c4e55d564a0..fe497498c4b 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3150,7 +3150,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error.obligation.predicate.kind().skip_binder(), ) { (ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)), _) - if self.tcx.lang_items().index_trait() == Some(predicate.trait_ref.def_id) => + if self.tcx.is_lang_item(predicate.trait_ref.def_id, LangItem::Index) => { seen_preds.insert(error.obligation.predicate.kind().skip_binder()); } diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index b7937f458b3..3cecbfd4275 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -488,7 +488,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { let remaining_errors_if_fallback_to = |fallback| { self.probe(|_| { let obligations = self.fulfillment_cx.borrow().pending_obligations(); - let ocx = ObligationCtxt::new(&self.infcx); + let ocx = ObligationCtxt::new_with_diagnostics(&self.infcx); ocx.register_obligations(obligations.iter().cloned()); for &diverging_vid in diverging_vids { @@ -506,14 +506,18 @@ impl<'tcx> FnCtxt<'_, 'tcx> { // then this code will be broken by the never type fallback change.qba let unit_errors = remaining_errors_if_fallback_to(self.tcx.types.unit); if unit_errors.is_empty() - && let never_errors = remaining_errors_if_fallback_to(self.tcx.types.never) - && !never_errors.is_empty() + && let mut never_errors = remaining_errors_if_fallback_to(self.tcx.types.never) + && let [ref mut never_error, ..] = never_errors.as_mut_slice() { + self.adjust_fulfillment_error_for_expr_obligation(never_error); self.tcx.emit_node_span_lint( lint::builtin::DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK, self.tcx.local_def_id_to_hir_id(self.body_id), self.tcx.def_span(self.body_id), - errors::DependencyOnUnitNeverTypeFallback {}, + errors::DependencyOnUnitNeverTypeFallback { + obligation_span: never_error.obligation.cause.span, + obligation: never_error.obligation.predicate, + }, ) } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 8a88e5a6ff4..9743dc7c69f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -489,7 +489,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); return true; } else if let ty::Adt(adt, _) = found_ty_inner.peel_refs().kind() - && Some(adt.did()) == self.tcx.lang_items().string() + && self.tcx.is_lang_item(adt.did(), LangItem::String) && peeled.is_str() // `Result::map`, conversely, does not take ref of the error type. && error_tys.is_none_or(|(found, expected)| { @@ -3147,7 +3147,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } if let ty::Adt(adt, _) = expected_ty.kind() - && self.tcx.lang_items().range_struct() == Some(adt.did()) + && self.tcx.is_lang_item(adt.did(), LangItem::Range) { return; } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 28d738c11c8..abbfe452f5f 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1102,7 +1102,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { unsatisfied_predicates.iter().any(|(pred, _, _)| { match pred.kind().skip_binder() { ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => { - Some(pred.def_id()) == self.tcx.lang_items().sized_trait() + self.tcx.is_lang_item(pred.def_id(), LangItem::Sized) && pred.polarity == ty::PredicatePolarity::Positive } _ => false, @@ -1375,10 +1375,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty.is_str() || matches!( ty.kind(), - ty::Adt(adt, _) if Some(adt.did()) == self.tcx.lang_items().string() + ty::Adt(adt, _) if self.tcx.is_lang_item(adt.did(), LangItem::String) ) } - ty::Adt(adt, _) => Some(adt.did()) == self.tcx.lang_items().string(), + ty::Adt(adt, _) => self.tcx.is_lang_item(adt.did(), LangItem::String), _ => false, }; if is_string_or_ref_str && item_name.name == sym::iter { @@ -2723,7 +2723,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if tcx.is_diagnostic_item(sym::LocalKey, inner_id) { err.help("use `with` or `try_with` to access thread local storage"); - } else if Some(kind.did()) == tcx.lang_items().maybe_uninit() { + } else if tcx.is_lang_item(kind.did(), LangItem::MaybeUninit) { err.help(format!( "if this `{name}` has been initialized, \ use one of the `assume_init` methods to access the inner value" diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 220556fe256..aaf3d3ec34d 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -7,7 +7,7 @@ use rustc_errors::{ }; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; -use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability, Pat, PatKind}; +use rustc_hir::{self as hir, BindingMode, ByRef, HirId, LangItem, Mutability, Pat, PatKind}; use rustc_infer::infer; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; @@ -491,7 +491,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx; let expected = self.resolve_vars_if_possible(expected); pat_ty = match expected.kind() { - ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().string() => expected, + ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::String) => expected, ty::Str => Ty::new_static_str(tcx), _ => pat_ty, }; diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 5e9c3c64e39..fc7a22833ff 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -212,16 +212,16 @@ impl<'a, 'tcx> At<'a, 'tcx> { T: ToTrace<'tcx>, { match variance { - ty::Variance::Covariant => self.sub(define_opaque_types, expected, actual), - ty::Variance::Invariant => self.eq(define_opaque_types, expected, actual), - ty::Variance::Contravariant => self.sup(define_opaque_types, expected, actual), + ty::Covariant => self.sub(define_opaque_types, expected, actual), + ty::Invariant => self.eq(define_opaque_types, expected, actual), + ty::Contravariant => self.sup(define_opaque_types, expected, actual), // We could make this make sense but it's not readily // exposed and I don't feel like dealing with it. Note // that bivariance in general does a bit more than just // *nothing*, it checks that the types are the same // "modulo variance" basically. - ty::Variance::Bivariant => panic!("Bivariant given to `relate()`"), + ty::Bivariant => panic!("Bivariant given to `relate()`"), } } diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 7114b888718..b8dd501a721 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -345,7 +345,7 @@ impl<'tcx> InferCtxt<'tcx> { .args .iter() .enumerate() - .filter(|(i, _)| variances[*i] == ty::Variance::Invariant) + .filter(|(i, _)| variances[*i] == ty::Invariant) .filter_map(|(_, arg)| match arg.unpack() { GenericArgKind::Lifetime(r) => Some(r), GenericArgKind::Type(_) | GenericArgKind::Const(_) => None, @@ -441,7 +441,7 @@ where let variances = self.tcx.variances_of(*def_id); for (v, s) in std::iter::zip(variances, args.iter()) { - if *v != ty::Variance::Bivariant { + if *v != ty::Bivariant { s.visit_with(self); } } diff --git a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs index 488f435994d..c02ab98b2ba 100644 --- a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs +++ b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs @@ -102,9 +102,7 @@ where }; for (idx, s) in args.iter().enumerate() { - if variances.map(|variances| variances[idx]) - != Some(ty::Variance::Bivariant) - { + if variances.map(|variances| variances[idx]) != Some(ty::Bivariant) { s.visit_with(self); } } diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 87a2f0b4580..d6e57d85387 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -83,16 +83,16 @@ impl<'tcx> InferCtxt<'tcx> { // mention `?0`. if self.next_trait_solver() { let (lhs, rhs, direction) = match instantiation_variance { - ty::Variance::Invariant => { + ty::Invariant => { (generalized_ty.into(), source_ty.into(), AliasRelationDirection::Equate) } - ty::Variance::Covariant => { + ty::Covariant => { (generalized_ty.into(), source_ty.into(), AliasRelationDirection::Subtype) } - ty::Variance::Contravariant => { + ty::Contravariant => { (source_ty.into(), generalized_ty.into(), AliasRelationDirection::Subtype) } - ty::Variance::Bivariant => unreachable!("bivariant generalization"), + ty::Bivariant => unreachable!("bivariant generalization"), }; relation.register_predicates([ty::PredicateKind::AliasRelate(lhs, rhs, direction)]); @@ -192,7 +192,7 @@ impl<'tcx> InferCtxt<'tcx> { relation.span(), relation.structurally_relate_aliases(), target_vid, - ty::Variance::Invariant, + ty::Invariant, source_ct, )?; @@ -210,14 +210,14 @@ impl<'tcx> InferCtxt<'tcx> { // generalized const and the source. if target_is_expected { relation.relate_with_variance( - ty::Variance::Invariant, + ty::Invariant, ty::VarianceDiagInfo::default(), generalized_ct, source_ct, )?; } else { relation.relate_with_variance( - ty::Variance::Invariant, + ty::Invariant, ty::VarianceDiagInfo::default(), source_ct, generalized_ct, @@ -411,7 +411,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> { a_arg: ty::GenericArgsRef<'tcx>, b_arg: ty::GenericArgsRef<'tcx>, ) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> { - if self.ambient_variance == ty::Variance::Invariant { + if self.ambient_variance == ty::Invariant { // Avoid fetching the variance if we are in an invariant // context; no need, and it can induce dependency cycles // (e.g., #41849). @@ -667,7 +667,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> { // structural. ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => { let args = self.relate_with_variance( - ty::Variance::Invariant, + ty::Invariant, ty::VarianceDiagInfo::default(), args, args, diff --git a/compiler/rustc_infer/src/infer/relate/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs index cc17e60a79b..067004ecaeb 100644 --- a/compiler/rustc_infer/src/infer/relate/glb.rs +++ b/compiler/rustc_infer/src/infer/relate/glb.rs @@ -94,12 +94,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Glb<'_, '_, 'tcx> { // When higher-ranked types are involved, computing the GLB is // very challenging, switch to invariance. This is obviously // overly conservative but works ok in practice. - self.relate_with_variance( - ty::Variance::Invariant, - ty::VarianceDiagInfo::default(), - a, - b, - )?; + self.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)?; Ok(a) } else { Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?)) diff --git a/compiler/rustc_infer/src/infer/relate/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs index e9d300d349c..2184416b4cc 100644 --- a/compiler/rustc_infer/src/infer/relate/lub.rs +++ b/compiler/rustc_infer/src/infer/relate/lub.rs @@ -94,12 +94,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Lub<'_, '_, 'tcx> { // When higher-ranked types are involved, computing the LUB is // very challenging, switch to invariance. This is obviously // overly conservative but works ok in practice. - self.relate_with_variance( - ty::Variance::Invariant, - ty::VarianceDiagInfo::default(), - a, - b, - )?; + self.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)?; Ok(a) } else { Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?)) diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index f7b2f11e3d7..f2bec9392d5 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -42,7 +42,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> { a_arg: ty::GenericArgsRef<'tcx>, b_arg: ty::GenericArgsRef<'tcx>, ) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> { - if self.ambient_variance == ty::Variance::Invariant { + if self.ambient_variance == ty::Invariant { // Avoid fetching the variance if we are in an invariant // context; no need, and it can induce dependency cycles // (e.g., #41849). @@ -325,23 +325,23 @@ impl<'tcx> PredicateEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> { fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { self.register_predicates([ty::Binder::dummy(match self.ambient_variance { - ty::Variance::Covariant => ty::PredicateKind::AliasRelate( + ty::Covariant => ty::PredicateKind::AliasRelate( a.into(), b.into(), ty::AliasRelationDirection::Subtype, ), // a :> b is b <: a - ty::Variance::Contravariant => ty::PredicateKind::AliasRelate( + ty::Contravariant => ty::PredicateKind::AliasRelate( b.into(), a.into(), ty::AliasRelationDirection::Subtype, ), - ty::Variance::Invariant => ty::PredicateKind::AliasRelate( + ty::Invariant => ty::PredicateKind::AliasRelate( a.into(), b.into(), ty::AliasRelationDirection::Equate, ), - ty::Variance::Bivariant => { + ty::Bivariant => { unreachable!("Expected bivariance to be handled in relate_with_variance") } })]); diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs index b671dfaa0d1..911975f6179 100644 --- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs +++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs @@ -3,7 +3,7 @@ use crate::{ LateContext, LateLintPass, LintContext, }; -use rustc_hir as hir; +use rustc_hir::{self as hir, LangItem}; use rustc_middle::ty; use rustc_session::lint::FutureIncompatibilityReason; use rustc_session::{declare_lint, declare_lint_pass}; @@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait { // the trait is a `Deref` implementation && let Some(trait_) = &impl_.of_trait && let Some(did) = trait_.trait_def_id() - && Some(did) == tcx.lang_items().deref_trait() + && tcx.is_lang_item(did, LangItem::Deref) // the self type is `dyn t_principal` && let self_ty = tcx.type_of(item.owner_id).instantiate_identity() && let ty::Dynamic(data, _, ty::Dyn) = self_ty.kind() diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index c9d67854112..2dc2a0efdf0 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -2,7 +2,7 @@ use crate::lints::{NonFmtPanicBraces, NonFmtPanicUnused}; use crate::{fluent_generated as fluent, LateContext, LateLintPass, LintContext}; use rustc_ast as ast; use rustc_errors::Applicability; -use rustc_hir as hir; +use rustc_hir::{self as hir, LangItem}; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; use rustc_middle::lint::in_external_macro; @@ -53,8 +53,8 @@ impl<'tcx> LateLintPass<'tcx> for NonPanicFmt { if let &ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(f).kind() { let f_diagnostic_name = cx.tcx.get_diagnostic_name(def_id); - if Some(def_id) == cx.tcx.lang_items().begin_panic_fn() - || Some(def_id) == cx.tcx.lang_items().panic_fn() + if cx.tcx.is_lang_item(def_id, LangItem::BeginPanic) + || cx.tcx.is_lang_item(def_id, LangItem::Panic) || f_diagnostic_name == Some(sym::panic_str_2015) { if let Some(id) = f.span.ctxt().outer_expn_data().macro_def_id { @@ -153,7 +153,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc ty::Ref(_, r, _) if r.is_str(), ) || matches!( ty.ty_adt_def(), - Some(ty_def) if Some(ty_def.did()) == cx.tcx.lang_items().string(), + Some(ty_def) if cx.tcx.is_lang_item(ty_def.did(), LangItem::String), ); let infcx = cx.tcx.infer_ctxt().build(); diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs index 4d1b1dc4fb7..6983e7abbd6 100644 --- a/compiler/rustc_lint/src/traits.rs +++ b/compiler/rustc_lint/src/traits.rs @@ -2,7 +2,7 @@ use crate::lints::{DropGlue, DropTraitConstraintsDiag}; use crate::LateContext; use crate::LateLintPass; use crate::LintContext; -use rustc_hir as hir; +use rustc_hir::{self as hir, LangItem}; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::symbol::sym; @@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { continue; }; let def_id = trait_predicate.trait_ref.def_id; - if cx.tcx.lang_items().drop_trait() == Some(def_id) { + if cx.tcx.is_lang_item(def_id, LangItem::Drop) { // Explicitly allow `impl Drop`, a drop-guards-as-unnameable-type pattern. if trait_predicate.trait_ref.self_ty().is_impl_trait() { continue; diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index c8da9f179e7..7a1aa4043be 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -10,9 +10,9 @@ use rustc_ast as ast; use rustc_ast::util::{classify, parser}; use rustc_ast::{ExprKind, StmtKind}; use rustc_errors::{pluralize, MultiSpan}; -use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir, LangItem}; use rustc_infer::traits::util::elaborate; use rustc_middle::ty::adjustment; use rustc_middle::ty::{self, Ty}; @@ -289,7 +289,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { is_ty_must_use(cx, boxed_ty, expr, span) .map(|inner| MustUsePath::Boxed(Box::new(inner))) } - ty::Adt(def, args) if cx.tcx.lang_items().pin_type() == Some(def.did()) => { + ty::Adt(def, args) if cx.tcx.is_lang_item(def.did(), LangItem::Pin) => { let pinned_ty = args.type_at(0); is_ty_must_use(cx, pinned_ty, expr, span) .map(|inner| MustUsePath::Pinned(Box::new(inner))) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 89da0df8575..d7840a2d516 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2020,7 +2020,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // if this is an impl of `CoerceUnsized`, create its // "unsized info", else just store None - if Some(trait_ref.def_id) == tcx.lang_items().coerce_unsized_trait() { + if tcx.is_lang_item(trait_ref.def_id, LangItem::CoerceUnsized) { let coerce_unsized_info = tcx.coerce_unsized_info(def_id).unwrap(); record!(self.tables.coerce_unsized_info[def_id] <- coerce_unsized_info); } diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs index 4fd1c1f4a1b..e76d7af6e4a 100644 --- a/compiler/rustc_middle/src/middle/lang_items.rs +++ b/compiler/rustc_middle/src/middle/lang_items.rs @@ -23,6 +23,10 @@ impl<'tcx> TyCtxt<'tcx> { }) } + pub fn is_lang_item(self, def_id: DefId, lang_item: LangItem) -> bool { + self.lang_items().get(lang_item) == Some(def_id) + } + /// Given a [`DefId`] of one of the [`Fn`], [`FnMut`] or [`FnOnce`] traits, /// returns a corresponding [`ty::ClosureKind`]. /// For any other [`DefId`] return `None`. diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index ebe77a1abfd..3edc5fe36cd 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1490,7 +1490,8 @@ pub enum BinOp { BitOr, /// The `<<` operator (shift left) /// - /// The offset is (uniquely) determined as follows: + /// The offset is given by `RHS.rem_euclid(LHS::BITS)`. + /// In other words, it is (uniquely) determined as follows: /// - it is "equal modulo LHS::BITS" to the RHS /// - it is in the range `0..LHS::BITS` Shl, @@ -1498,7 +1499,8 @@ pub enum BinOp { ShlUnchecked, /// The `>>` operator (shift right) /// - /// The offset is (uniquely) determined as follows: + /// The offset is given by `RHS.rem_euclid(LHS::BITS)`. + /// In other words, it is (uniquely) determined as follows: /// - it is "equal modulo LHS::BITS" to the RHS /// - it is in the range `0..LHS::BITS` /// diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index a89ebe46c37..684b3233cfd 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -8,9 +8,9 @@ use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::HashingControls; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_errors::ErrorGuaranteed; -use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir, LangItem}; use rustc_index::{IndexSlice, IndexVec}; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_query_system::ich::StableHashingContext; @@ -274,16 +274,16 @@ impl AdtDefData { if tcx.has_attr(did, sym::fundamental) { flags |= AdtFlags::IS_FUNDAMENTAL; } - if Some(did) == tcx.lang_items().phantom_data() { + if tcx.is_lang_item(did, LangItem::PhantomData) { flags |= AdtFlags::IS_PHANTOM_DATA; } - if Some(did) == tcx.lang_items().owned_box() { + if tcx.is_lang_item(did, LangItem::OwnedBox) { flags |= AdtFlags::IS_BOX; } - if Some(did) == tcx.lang_items().manually_drop() { + if tcx.is_lang_item(did, LangItem::ManuallyDrop) { flags |= AdtFlags::IS_MANUALLY_DROP; } - if Some(did) == tcx.lang_items().unsafe_cell_type() { + if tcx.is_lang_item(did, LangItem::UnsafeCell) { flags |= AdtFlags::IS_UNSAFE_CELL; } if is_anonymous { diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index a887047f62f..bdf90cbb25b 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -699,26 +699,25 @@ impl<'tcx> Instance<'tcx> { }; let coroutine_kind = tcx.coroutine_kind(coroutine_def_id).unwrap(); - let lang_items = tcx.lang_items(); - let coroutine_callable_item = if Some(trait_id) == lang_items.future_trait() { + let coroutine_callable_item = if tcx.is_lang_item(trait_id, LangItem::Future) { assert_matches!( coroutine_kind, hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _) ); hir::LangItem::FuturePoll - } else if Some(trait_id) == lang_items.iterator_trait() { + } else if tcx.is_lang_item(trait_id, LangItem::Iterator) { assert_matches!( coroutine_kind, hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _) ); hir::LangItem::IteratorNext - } else if Some(trait_id) == lang_items.async_iterator_trait() { + } else if tcx.is_lang_item(trait_id, LangItem::AsyncIterator) { assert_matches!( coroutine_kind, hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _) ); hir::LangItem::AsyncIteratorPollNext - } else if Some(trait_id) == lang_items.coroutine_trait() { + } else if tcx.is_lang_item(trait_id, LangItem::Coroutine) { assert_matches!(coroutine_kind, hir::CoroutineKind::Coroutine(_)); hir::LangItem::CoroutineResume } else { diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 56945bf6be4..02c0d41f619 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -9,6 +9,7 @@ use rustc_errors::{ }; use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_hir::LangItem; use rustc_index::IndexVec; use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable}; use rustc_session::config::OptLevel; @@ -850,7 +851,7 @@ where // and we rely on this layout information to trigger a panic in // `std::mem::uninitialized::<&dyn Trait>()`, for example. if let ty::Adt(def, args) = metadata.kind() - && Some(def.did()) == tcx.lang_items().dyn_metadata() + && tcx.is_lang_item(def.did(), LangItem::DynMetadata) && let ty::Dynamic(data, _, ty::Dyn) = args.type_at(0).kind() { mk_dyn_vtable(data.principal()) @@ -1169,7 +1170,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: SpecAbi) -> // This is not part of `codegen_fn_attrs` as it can differ between crates // and therefore cannot be computed in core. if tcx.sess.opts.unstable_opts.panic_in_drop == PanicStrategy::Abort { - if Some(did) == tcx.lang_items().drop_in_place_fn() { + if tcx.is_lang_item(did, LangItem::DropInPlace) { return false; } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c322c87bce4..5a94a53e175 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -16,7 +16,6 @@ pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeV pub use self::AssocItemContainer::*; pub use self::BorrowKind::*; pub use self::IntVarValue::*; -pub use self::Variance::*; use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason}; use crate::metadata::ModChild; use crate::middle::privacy::EffectiveVisibilities; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 662eafd0ccb..de1796d4800 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -999,7 +999,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let trait_ref = bound_predicate.rebind(pred.trait_ref); // Don't print `+ Sized`, but rather `+ ?Sized` if absent. - if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() { + if tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) { match pred.polarity { ty::PredicatePolarity::Positive => { has_sized_bound = true; @@ -1254,14 +1254,14 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } entry.has_fn_once = true; return; - } else if Some(trait_def_id) == self.tcx().lang_items().fn_mut_trait() { + } else if self.tcx().is_lang_item(trait_def_id, LangItem::FnMut) { let super_trait_ref = supertraits_for_pretty_printing(self.tcx(), trait_ref) .find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait) .unwrap(); fn_traits.entry(super_trait_ref).or_default().fn_mut_trait_ref = Some(trait_ref); return; - } else if Some(trait_def_id) == self.tcx().lang_items().fn_trait() { + } else if self.tcx().is_lang_item(trait_def_id, LangItem::Fn) { let super_trait_ref = supertraits_for_pretty_printing(self.tcx(), trait_ref) .find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait) .unwrap(); diff --git a/compiler/rustc_middle/src/util/call_kind.rs b/compiler/rustc_middle/src/util/call_kind.rs index a4cbfe86711..dc1d73684f4 100644 --- a/compiler/rustc_middle/src/util/call_kind.rs +++ b/compiler/rustc_middle/src/util/call_kind.rs @@ -117,19 +117,19 @@ pub fn call_kind<'tcx>( kind.unwrap_or_else(|| { // This isn't a 'special' use of `self` debug!(?method_did, ?fn_call_span); - let desugaring = if Some(method_did) == tcx.lang_items().into_iter_fn() + let desugaring = if tcx.is_lang_item(method_did, LangItem::IntoIterIntoIter) && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop) { Some((CallDesugaringKind::ForLoopIntoIter, method_args.type_at(0))) } else if fn_call_span.desugaring_kind() == Some(DesugaringKind::QuestionMark) { - if Some(method_did) == tcx.lang_items().branch_fn() { + if tcx.is_lang_item(method_did, LangItem::TryTraitBranch) { Some((CallDesugaringKind::QuestionBranch, method_args.type_at(0))) - } else if Some(method_did) == tcx.lang_items().from_residual_fn() { + } else if tcx.is_lang_item(method_did, LangItem::TryTraitFromResidual) { Some((CallDesugaringKind::QuestionFromResidual, method_args.type_at(0))) } else { None } - } else if Some(method_did) == tcx.lang_items().from_output_fn() + } else if tcx.is_lang_item(method_did, LangItem::TryTraitFromOutput) && fn_call_span.desugaring_kind() == Some(DesugaringKind::TryBlock) { Some((CallDesugaringKind::TryBlockFromOutput, method_args.type_at(0))) diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index 4ae475d35d1..8c323188826 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -142,7 +142,7 @@ impl<'tcx> Value<TyCtxt<'tcx>> for &[ty::Variance] { && let Some(def_id) = frame.query.def_id { let n = tcx.generics_of(def_id).own_params.len(); - vec![ty::Variance::Bivariant; n].leak() + vec![ty::Bivariant; n].leak() } else { span_bug!( cycle_error.usage.as_ref().unwrap().0, diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index b783eba8c4e..3b69058d3cb 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -2,6 +2,7 @@ use crate::build::{parse_float_into_constval, Builder}; use rustc_ast as ast; +use rustc_hir::LangItem; use rustc_middle::mir; use rustc_middle::mir::interpret::{Allocation, LitToConstError, LitToConstInput, Scalar}; use rustc_middle::mir::*; @@ -142,7 +143,7 @@ fn lit_to_mir_constant<'tcx>( let id = tcx.allocate_bytes(data); ConstValue::Scalar(Scalar::from_pointer(id.into(), &tcx)) } - (ast::LitKind::CStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().c_str()) => + (ast::LitKind::CStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::CStr)) => { let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]); let allocation = tcx.mk_const_alloc(allocation); diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 54138789369..544f27b84e9 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -699,7 +699,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // exactly `T` (i.e., with invariance). The variance field, in // contrast, is intended to be used to relate `T` to the type of // `<expr>`. - ty::Variance::Invariant, + ty::Invariant, ), }, ); diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 2040071e76e..11d3e2a8180 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -141,7 +141,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let success_block = target_block(TestBranch::Success); let fail_block = target_block(TestBranch::Failure); if let ty::Adt(def, _) = ty.kind() - && Some(def.did()) == tcx.lang_items().string() + && tcx.is_lang_item(def.did(), LangItem::String) { if !tcx.features().string_deref_patterns { bug!( diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index a98e046d4dc..7b94867114d 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -1,4 +1,5 @@ use rustc_ast as ast; +use rustc_hir::LangItem; use rustc_middle::bug; use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; use rustc_middle::ty::{self, ParamEnv, ScalarInt, TyCtxt}; @@ -46,7 +47,7 @@ pub(crate) fn lit_to_const<'tcx>( (ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => { ty::ValTree::from_scalar_int((*n).into()) } - (ast::LitKind::CStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().c_str()) => + (ast::LitKind::CStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::CStr)) => { let bytes = data as &[u8]; ty::ValTree::from_raw_bytes(tcx, bytes) diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs index 54eafdd828a..95cd703dbb3 100644 --- a/compiler/rustc_mir_build/src/thir/cx/block.rs +++ b/compiler/rustc_mir_build/src/thir/cx/block.rs @@ -92,7 +92,7 @@ impl<'tcx> Cx<'tcx> { kind: PatKind::AscribeUserType { ascription: Ascription { annotation, - variance: ty::Variance::Covariant, + variance: ty::Covariant, }, subpattern: pattern, }, diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 158ca91fcf1..93db1f61853 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -525,7 +525,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { }; kind = PatKind::AscribeUserType { subpattern: Box::new(Pat { span, ty, kind }), - ascription: Ascription { annotation, variance: ty::Variance::Covariant }, + ascription: Ascription { annotation, variance: ty::Covariant }, }; } @@ -612,7 +612,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { annotation, // Note that use `Contravariant` here. See the // `variance` field documentation for details. - variance: ty::Variance::Contravariant, + variance: ty::Contravariant, }, }, ty: const_.ty(), diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index bdc59e84356..654020164db 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -454,8 +454,7 @@ where }); } - let skip_contents = - adt.is_union() || Some(adt.did()) == self.tcx().lang_items().manually_drop(); + let skip_contents = adt.is_union() || adt.is_manually_drop(); let contents_drop = if skip_contents { (self.succ, self.unwind) } else { diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs index f880476cec2..16977a63c59 100644 --- a/compiler/rustc_mir_transform/src/add_retag.rs +++ b/compiler/rustc_mir_transform/src/add_retag.rs @@ -4,6 +4,7 @@ //! of MIR building, and only after this pass we think of the program has having the //! normal MIR semantics. +use rustc_hir::LangItem; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -27,7 +28,7 @@ fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> b // References and Boxes (`noalias` sources) ty::Ref(..) => true, ty::Adt(..) if ty.is_box() => true, - ty::Adt(adt, _) if Some(adt.did()) == tcx.lang_items().ptr_unique() => true, + ty::Adt(adt, _) if tcx.is_lang_item(adt.did(), LangItem::PtrUnique) => true, // Compound types: recurse ty::Array(ty, _) | ty::Slice(ty) => { // This does not branch so we keep the depth the same. diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index fe2237dd2e9..2cbe0a01e9e 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -225,13 +225,8 @@ impl<'tcx> Inliner<'tcx> { // Normally, this shouldn't be required, but trait normalization failure can create a // validation ICE. let output_type = callee_body.return_ty(); - if !util::relate_types( - self.tcx, - self.param_env, - ty::Variance::Covariant, - output_type, - destination_ty, - ) { + if !util::relate_types(self.tcx, self.param_env, ty::Covariant, output_type, destination_ty) + { trace!(?output_type, ?destination_ty); return Err("failed to normalize return type"); } @@ -261,13 +256,8 @@ impl<'tcx> Inliner<'tcx> { self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter()) { let input_type = callee_body.local_decls[input].ty; - if !util::relate_types( - self.tcx, - self.param_env, - ty::Variance::Covariant, - input_type, - arg_ty, - ) { + if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty) + { trace!(?arg_ty, ?input_type); return Err("failed to normalize tuple argument type"); } @@ -276,13 +266,8 @@ impl<'tcx> Inliner<'tcx> { for (arg, input) in args.iter().zip(callee_body.args_iter()) { let input_type = callee_body.local_decls[input].ty; let arg_ty = arg.node.ty(&caller_body.local_decls, self.tcx); - if !util::relate_types( - self.tcx, - self.param_env, - ty::Variance::Covariant, - input_type, - arg_ty, - ) { + if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty) + { trace!(?arg_ty, ?input_type); return Err("failed to normalize argument type"); } 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 aa9c87d8f80..41643f20285 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -561,7 +561,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { // If projection of Discriminant then compare with `Ty::discriminant_ty` if let ty::Alias(ty::Projection, ty::AliasTy { args, def_id, .. }) = expected_ty.kind() - && Some(*def_id) == self.tcx.lang_items().discriminant_type() + && self.tcx.is_lang_item(*def_id, LangItem::Discriminant) && args.first().unwrap().as_type().unwrap().discriminant_ty(self.tcx) == operand_ty { return; diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index f19c34cae7a..c2108795372 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -1,4 +1,5 @@ use rustc_data_structures::flat_map_in_place::FlatMapInPlace; +use rustc_hir::LangItem; use rustc_index::bit_set::{BitSet, GrowableBitSet}; use rustc_index::IndexVec; use rustc_middle::bug; @@ -70,7 +71,7 @@ fn escaping_locals<'tcx>( // Exclude #[repr(simd)] types so that they are not de-optimized into an array return true; } - if Some(def.did()) == tcx.lang_items().dyn_metadata() { + if tcx.is_lang_item(def.did(), LangItem::DynMetadata) { // codegen wants to see the `DynMetadata<T>`, // not the inner reference-to-opaque-type. return true; diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 586c1254995..ea23bbc2a38 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -1,6 +1,7 @@ //! Validates the MIR to ensure that invariants are upheld. use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_hir::LangItem; use rustc_index::bit_set::BitSet; use rustc_index::IndexVec; use rustc_infer::traits::Reveal; @@ -689,7 +690,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } ty::Adt(adt_def, args) => { // see <https://github.com/rust-lang/rust/blob/7601adcc764d42c9f2984082b49948af652df986/compiler/rustc_middle/src/ty/layout.rs#L861-L864> - if Some(adt_def.did()) == self.tcx.lang_items().dyn_metadata() { + if self.tcx.is_lang_item(adt_def.did(), LangItem::DynMetadata) { self.fail( location, format!( diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 61680dbfaf5..eb71eeac501 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -593,7 +593,7 @@ fn check_recursion_limit<'tcx>( let recursion_depth = recursion_depths.get(&def_id).cloned().unwrap_or(0); debug!(" => recursion depth={}", recursion_depth); - let adjusted_recursion_depth = if Some(def_id) == tcx.lang_items().drop_in_place_fn() { + let adjusted_recursion_depth = if tcx.is_lang_item(def_id, LangItem::DropInPlace) { // HACK: drop_in_place creates tight monomorphization loops. Give // it more margin. recursion_depth / 4 @@ -945,7 +945,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.lang_items().get(LangItem::PanicNounwind).unwrap(); + let def_id = tcx.require_lang_item(LangItem::PanicNounwind, None); let panic_instance = Instance::mono(tcx, def_id); if should_codegen_locally(tcx, panic_instance) { output.push(create_fn_mono_item(tcx, panic_instance, source)); diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 336341f4e74..14b5b22dc64 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -104,6 +104,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdSet, LOCAL_CRATE}; use rustc_hir::definitions::DefPathDataName; +use rustc_hir::LangItem; use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel}; @@ -813,7 +814,7 @@ fn mono_item_visibility<'tcx>( // from the `main` symbol we'll generate later. // // This may be fixable with a new `InstanceDef` perhaps? Unsure! - if tcx.lang_items().start_fn() == Some(def_id) { + if tcx.is_lang_item(def_id, LangItem::Start) { *can_be_internalized = false; return Visibility::Hidden; } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index b0adc3775f6..fa711d932b6 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3281,17 +3281,19 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } self.visit_path(&delegation.path, delegation.id); if let Some(body) = &delegation.body { - // `PatBoundCtx` is not necessary in this context - let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())]; - - let span = delegation.path.segments.last().unwrap().ident.span; - self.fresh_binding( - Ident::new(kw::SelfLower, span), - delegation.id, - PatternSource::FnParam, - &mut bindings, - ); - self.visit_block(body); + self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| { + // `PatBoundCtx` is not necessary in this context + let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())]; + + let span = delegation.path.segments.last().unwrap().ident.span; + this.fresh_binding( + Ident::new(kw::SelfLower, span), + delegation.id, + PatternSource::FnParam, + &mut bindings, + ); + this.visit_block(body); + }); } } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 9eeb0da7ed2..be24755d4c5 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1021,12 +1021,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { }, ); let is_assoc_fn = self.self_type_is_available(); + let self_from_macro = "a `self` parameter, but a macro invocation can only \ + access identifiers it receives from parameters"; if let Some((fn_kind, span)) = &self.diag_metadata.current_function { // The current function has a `self` parameter, but we were unable to resolve // a reference to `self`. This can only happen if the `self` identifier we // are resolving came from a different hygiene context. if fn_kind.decl().inputs.get(0).is_some_and(|p| p.is_self()) { - err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters"); + err.span_label(*span, format!("this function has {self_from_macro}")); } else { let doesnt = if is_assoc_fn { let (span, sugg) = fn_kind @@ -1068,14 +1070,18 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } } } else if let Some(item_kind) = self.diag_metadata.current_item { - err.span_label( - item_kind.ident.span, - format!( - "`self` not allowed in {} {}", - item_kind.kind.article(), - item_kind.kind.descr() - ), - ); + if matches!(item_kind.kind, ItemKind::Delegation(..)) { + err.span_label(item_kind.span, format!("delegation supports {self_from_macro}")); + } else { + err.span_label( + item_kind.ident.span, + format!( + "`self` not allowed in {} {}", + item_kind.kind.article(), + item_kind.kind.descr() + ), + ); + } } true } 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 2fbfb93150e..2cb0c06e336 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 @@ -289,7 +289,7 @@ pub fn transform_instance<'tcx>( options: TransformTyOptions, ) -> Instance<'tcx> { if (matches!(instance.def, ty::InstanceDef::Virtual(..)) - && Some(instance.def_id()) == tcx.lang_items().drop_in_place_fn()) + && tcx.is_lang_item(instance.def_id(), LangItem::DropInPlace)) || matches!(instance.def, ty::InstanceDef::DropGlue(..)) { // Adjust the type ids of DropGlues diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index a8688c88601..981231694bb 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -6,6 +6,7 @@ #![allow(rustc::usage_of_qualified_ty)] use rustc_abi::HasDataLayout; +use rustc_hir::LangItem; use rustc_middle::ty::layout::{ FnAbiOf, FnAbiOfHelpers, HasParamEnv, HasTyCtxt, LayoutOf, LayoutOfHelpers, }; @@ -295,7 +296,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let def_id = def.0.internal(&mut *tables, tcx); - tables.tcx.lang_items().c_str() == Some(def_id) + tables.tcx.is_lang_item(def_id, LangItem::CStr) } fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig { diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 73bc87dc9ab..e3cd7187e77 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -866,10 +866,10 @@ impl<'tcx> Stable<'tcx> for ty::Variance { type T = stable_mir::mir::Variance; fn stable(&self, _: &mut Tables<'_>) -> Self::T { match self { - ty::Variance::Bivariant => stable_mir::mir::Variance::Bivariant, - ty::Variance::Contravariant => stable_mir::mir::Variance::Contravariant, - ty::Variance::Covariant => stable_mir::mir::Variance::Covariant, - ty::Variance::Invariant => stable_mir::mir::Variance::Invariant, + ty::Bivariant => stable_mir::mir::Variance::Bivariant, + ty::Contravariant => stable_mir::mir::Variance::Contravariant, + ty::Covariant => stable_mir::mir::Variance::Covariant, + ty::Invariant => stable_mir::mir::Variance::Invariant, } } } diff --git a/compiler/rustc_trait_selection/src/solve/alias_relate.rs b/compiler/rustc_trait_selection/src/solve/alias_relate.rs index 59a8de99b8f..4e52caa5a5b 100644 --- a/compiler/rustc_trait_selection/src/solve/alias_relate.rs +++ b/compiler/rustc_trait_selection/src/solve/alias_relate.rs @@ -61,8 +61,8 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { trace!(?lhs, ?rhs); let variance = match direction { - ty::AliasRelationDirection::Equate => ty::Variance::Invariant, - ty::AliasRelationDirection::Subtype => ty::Variance::Covariant, + ty::AliasRelationDirection::Equate => ty::Invariant, + ty::AliasRelationDirection::Subtype => ty::Covariant, }; match (lhs.to_alias_term(), rhs.to_alias_term()) { (None, None) => { @@ -78,7 +78,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { self.relate_rigid_alias_non_alias( param_env, alias, - variance.xform(ty::Variance::Contravariant), + variance.xform(ty::Contravariant), lhs, )?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index b51efd339c4..9c18366887b 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -1,6 +1,7 @@ //! Code shared by trait and projection goals for candidate assembly. use rustc_hir::def_id::DefId; +use rustc_hir::LangItem; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::query::NoSolution; use rustc_middle::bug; @@ -481,7 +482,6 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { candidates: &mut Vec<Candidate<'tcx>>, ) { let tcx = self.interner(); - let lang_items = tcx.lang_items(); let trait_def_id = goal.predicate.trait_def_id(tcx); // N.B. When assembling built-in candidates for lang items that are also @@ -497,43 +497,43 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { G::consider_auto_trait_candidate(self, goal) } else if tcx.trait_is_alias(trait_def_id) { G::consider_trait_alias_candidate(self, goal) - } else if lang_items.sized_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::Sized) { G::consider_builtin_sized_candidate(self, goal) - } else if lang_items.copy_trait() == Some(trait_def_id) - || lang_items.clone_trait() == Some(trait_def_id) + } else if tcx.is_lang_item(trait_def_id, LangItem::Copy) + || tcx.is_lang_item(trait_def_id, LangItem::Clone) { G::consider_builtin_copy_clone_candidate(self, goal) - } else if lang_items.pointer_like() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::PointerLike) { G::consider_builtin_pointer_like_candidate(self, goal) - } else if lang_items.fn_ptr_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::FnPtrTrait) { G::consider_builtin_fn_ptr_trait_candidate(self, goal) } else if let Some(kind) = self.interner().fn_trait_kind_from_def_id(trait_def_id) { G::consider_builtin_fn_trait_candidates(self, goal, kind) } else if let Some(kind) = self.interner().async_fn_trait_kind_from_def_id(trait_def_id) { G::consider_builtin_async_fn_trait_candidates(self, goal, kind) - } else if lang_items.async_fn_kind_helper() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::AsyncFnKindHelper) { G::consider_builtin_async_fn_kind_helper_candidate(self, goal) - } else if lang_items.tuple_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::Tuple) { G::consider_builtin_tuple_candidate(self, goal) - } else if lang_items.pointee_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::PointeeTrait) { G::consider_builtin_pointee_candidate(self, goal) - } else if lang_items.future_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::Future) { G::consider_builtin_future_candidate(self, goal) - } else if lang_items.iterator_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::Iterator) { G::consider_builtin_iterator_candidate(self, goal) - } else if lang_items.fused_iterator_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::FusedIterator) { G::consider_builtin_fused_iterator_candidate(self, goal) - } else if lang_items.async_iterator_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::AsyncIterator) { G::consider_builtin_async_iterator_candidate(self, goal) - } else if lang_items.coroutine_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::Coroutine) { G::consider_builtin_coroutine_candidate(self, goal) - } else if lang_items.discriminant_kind_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::DiscriminantKind) { G::consider_builtin_discriminant_kind_candidate(self, goal) - } else if lang_items.async_destruct_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::AsyncDestruct) { G::consider_builtin_async_destruct_candidate(self, goal) - } else if lang_items.destruct_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::Destruct) { G::consider_builtin_destruct_candidate(self, goal) - } else if lang_items.transmute_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::TransmuteTrait) { G::consider_builtin_transmute_candidate(self, goal) } else { Err(NoSolution) @@ -543,7 +543,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { // There may be multiple unsize candidates for a trait with several supertraits: // `trait Foo: Bar<A> + Bar<B>` and `dyn Foo: Unsize<dyn Bar<_>>` - if lang_items.unsize_trait() == Some(trait_def_id) { + if tcx.is_lang_item(trait_def_id, LangItem::Unsize) { candidates.extend(G::consider_structural_builtin_unsize_candidates(self, goal)); } } diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index 50253d81528..c3e4057f5e0 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -40,7 +40,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { Ok(res) => Ok(res), Err(NoSolution) => { let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal; - self.relate_rigid_alias_non_alias(param_env, alias, ty::Variance::Invariant, term)?; + self.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } @@ -392,9 +392,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { output_coroutine_ty, coroutine_return_ty, }| { - let lang_items = tcx.lang_items(); - let (projection_term, term) = if Some(goal.predicate.def_id()) - == lang_items.call_once_future() + let (projection_term, term) = if tcx + .is_lang_item(goal.predicate.def_id(), LangItem::CallOnceFuture) { ( ty::AliasTerm::new( @@ -404,7 +403,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ), output_coroutine_ty.into(), ) - } else if Some(goal.predicate.def_id()) == lang_items.call_ref_future() { + } else if tcx.is_lang_item(goal.predicate.def_id(), LangItem::CallRefFuture) { ( ty::AliasTerm::new( tcx, @@ -417,7 +416,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ), output_coroutine_ty.into(), ) - } else if Some(goal.predicate.def_id()) == lang_items.async_fn_once_output() { + } else if tcx.is_lang_item(goal.predicate.def_id(), LangItem::AsyncFnOnceOutput) + { ( ty::AliasTerm::new( tcx, @@ -719,10 +719,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { let coroutine = args.as_coroutine(); - let lang_items = tcx.lang_items(); - let term = if Some(goal.predicate.def_id()) == lang_items.coroutine_return() { + let term = if tcx.is_lang_item(goal.predicate.def_id(), LangItem::CoroutineReturn) { coroutine.return_ty().into() - } else if Some(goal.predicate.def_id()) == lang_items.coroutine_yield() { + } else if tcx.is_lang_item(goal.predicate.def_id(), LangItem::CoroutineYield) { coroutine.yield_ty().into() } else { bug!( diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index a741f488901..f631a21a82c 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -802,14 +802,13 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { ); // The type must be `Sized` to be unsized. - if let Some(sized_def_id) = tcx.lang_items().sized_trait() { - ecx.add_goal( - GoalSource::ImplWhereBound, - goal.with(tcx, ty::TraitRef::new(tcx, sized_def_id, [a_ty])), - ); - } else { - return Err(NoSolution); - } + ecx.add_goal( + GoalSource::ImplWhereBound, + goal.with( + tcx, + ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, None), [a_ty]), + ), + ); // The type must outlive the lifetime of the `dyn` we're unsizing into. ecx.add_goal(GoalSource::Misc, goal.with(tcx, ty::OutlivesPredicate(a_ty, b_region))); @@ -991,7 +990,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { tcx, ty::TraitRef::new( tcx, - tcx.lang_items().unsize_trait().unwrap(), + tcx.require_lang_item(LangItem::Unsize, None), [a_tail_ty, b_tail_ty], ), ), @@ -1034,7 +1033,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { tcx, ty::TraitRef::new( tcx, - tcx.lang_items().unsize_trait().unwrap(), + tcx.require_lang_item(LangItem::Unsize, None), [a_last_ty, b_last_ty], ), ), @@ -1076,7 +1075,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { // takes precedence over the structural auto trait candidate being // assembled. ty::Coroutine(def_id, _) - if Some(goal.predicate.def_id()) == self.interner().lang_items().unpin_trait() => + if self.interner().is_lang_item(goal.predicate.def_id(), LangItem::Unpin) => { match self.interner().coroutine_movability(def_id) { Movability::Static => Some(Err(NoSolution)), diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 4604c132835..f632f1ad4f2 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -794,7 +794,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) = obligation.predicate.kind().skip_binder() - && Some(trait_pred.def_id()) == self.tcx.lang_items().sized_trait() + && self.tcx.is_lang_item(trait_pred.def_id(), LangItem::Sized) { // Don't suggest calling to turn an unsized type into a sized type return false; @@ -1106,7 +1106,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .iter() .find_map(|pred| { if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder() - && Some(proj.projection_term.def_id) == self.tcx.lang_items().fn_once_output() + && self.tcx.is_lang_item(proj.projection_term.def_id,LangItem::FnOnceOutput) // args tuple will always be args[1] && let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind() { @@ -1123,7 +1123,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ty::Dynamic(data, _, ty::Dyn) => { data.iter().find_map(|pred| { if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder() - && Some(proj.def_id) == self.tcx.lang_items().fn_once_output() + && self.tcx.is_lang_item(proj.def_id, LangItem::FnOnceOutput) // for existential projection, args are shifted over by 1 && let ty::Tuple(args) = proj.args.type_at(0).kind() { @@ -1150,7 +1150,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; param_env.caller_bounds().iter().find_map(|pred| { if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder() - && Some(proj.projection_term.def_id) == self.tcx.lang_items().fn_once_output() + && self.tcx.is_lang_item(proj.projection_term.def_id, LangItem::FnOnceOutput) && proj.projection_term.self_ty() == found // args tuple will always be args[1] && let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind() @@ -1822,7 +1822,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { && box_path .res .opt_def_id() - .is_some_and(|def_id| Some(def_id) == self.tcx.lang_items().owned_box()) + .is_some_and(|def_id| self.tcx.is_lang_item(def_id, LangItem::OwnedBox)) { // Don't box `Box::new` vec![] @@ -2737,7 +2737,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { | ObligationCauseCode::ObjectTypeBound(..) => {} ObligationCauseCode::RustCall => { if let Some(pred) = predicate.as_trait_clause() - && Some(pred.def_id()) == tcx.lang_items().sized_trait() + && tcx.is_lang_item(pred.def_id(), LangItem::Sized) { err.note("argument required to be sized due to `extern \"rust-call\"` ABI"); } @@ -2790,7 +2790,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // Check for foreign traits being reachable. tcx.visible_parent_map(()).get(&def_id).is_some() }; - if Some(def_id) == tcx.lang_items().sized_trait() { + if tcx.is_lang_item(def_id, LangItem::Sized) { // Check if this is an implicit bound, even in foreign crates. if tcx .generics_of(item_def_id) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index aef9d482bec..9cd69f54c12 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -24,10 +24,10 @@ use rustc_data_structures::unord::UnordSet; use rustc_errors::codes::*; use rustc_errors::{pluralize, struct_span_code_err, Applicability, MultiSpan, StringPart}; use rustc_errors::{Diag, EmissionGuarantee, ErrorGuaranteed, FatalError, StashKey}; -use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; +use rustc_hir::{self as hir, LangItem}; use rustc_hir::{GenericParam, Item, Node}; use rustc_infer::infer::error_reporting::TypeErrCtxt; use rustc_infer::infer::{InferOk, TypeTrace}; @@ -118,7 +118,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // with more relevant type information and hide redundant E0282 errors. errors.sort_by_key(|e| match e.obligation.predicate.kind().skip_binder() { ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) - if Some(pred.def_id()) == self.tcx.lang_items().sized_trait() => + if self.tcx.is_lang_item(pred.def_id(), LangItem::Sized) => { 1 } @@ -513,7 +513,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let have_alt_message = message.is_some() || label.is_some(); let is_try_conversion = self.is_try_conversion(span, main_trait_ref.def_id()); let is_unsize = - Some(leaf_trait_ref.def_id()) == self.tcx.lang_items().unsize_trait(); + self.tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Unsize); let (message, notes, append_const_msg) = if is_try_conversion { ( Some(format!( @@ -586,14 +586,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); } - if Some(leaf_trait_ref.def_id()) == tcx.lang_items().tuple_trait() { + if tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Tuple) { self.add_tuple_trait_message( obligation.cause.code().peel_derives(), &mut err, ); } - if Some(leaf_trait_ref.def_id()) == tcx.lang_items().drop_trait() + if tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Drop) && predicate_is_const { err.note("`~const Drop` was renamed to `~const Destruct`"); @@ -648,7 +648,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let ObligationCauseCode::Coercion { source, target } = *obligation.cause.code().peel_derives() { - if Some(leaf_trait_ref.def_id()) == self.tcx.lang_items().sized_trait() { + if self.tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Sized) { self.suggest_borrowing_for_object_cast( &mut err, root_obligation, @@ -716,7 +716,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { self.suggest_remove_await(&obligation, &mut err); self.suggest_derive(&obligation, &mut err, leaf_trait_predicate); - if Some(leaf_trait_ref.def_id()) == tcx.lang_items().try_trait() { + if tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Try) { self.suggest_await_before_try( &mut err, &obligation, @@ -1020,7 +1020,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // doesn't extend the goal kind. This is worth reporting, but we can only do so // if we actually know which closure this goal comes from, so look at the cause // to see if we can extract that information. - if Some(trait_ref.def_id()) == self.tcx.lang_items().async_fn_kind_helper() + if self.tcx.is_lang_item(trait_ref.def_id(), LangItem::AsyncFnKindHelper) && let Some(found_kind) = trait_ref.skip_binder().args.type_at(0).to_opt_closure_kind() && let Some(expected_kind) = trait_ref.skip_binder().args.type_at(1).to_opt_closure_kind() @@ -1744,7 +1744,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let self_ty = pred.projection_term.self_ty(); with_forced_trimmed_paths! { - if Some(pred.projection_term.def_id) == self.tcx.lang_items().fn_once_output() { + if self.tcx.is_lang_item(pred.projection_term.def_id,LangItem::FnOnceOutput) { let fn_kind = self_ty.prefix_string(self.tcx); let item = match self_ty.kind() { ty::FnDef(def, _) => self.tcx.item_name(*def).to_string(), @@ -1754,7 +1754,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { "expected `{item}` to be a {fn_kind} that returns `{expected_ty}`, but it \ returns `{normalized_ty}`", )) - } else if Some(trait_def_id) == self.tcx.lang_items().future_trait() { + } else if self.tcx.is_lang_item(trait_def_id, LangItem::Future) { Some(format!( "expected `{self_ty}` to be a future that resolves to `{expected_ty}`, but it \ resolves to `{normalized_ty}`" @@ -1783,7 +1783,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ty::Bool => Some(0), ty::Char => Some(1), ty::Str => Some(2), - ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().string() => Some(2), + ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::String) => Some(2), ty::Int(..) | ty::Uint(..) | ty::Float(..) @@ -2342,7 +2342,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // avoid inundating the user with unnecessary errors, but we now // check upstream for type errors and don't add the obligations to // begin with in those cases. - if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) { + if self.tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) { match self.tainted_by_errors() { None => { let err = self.emit_inference_failure_err( @@ -2925,7 +2925,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let (Some(node), true) = ( self.tcx.hir().get_if_local(item_def_id), - Some(pred.def_id()) == self.tcx.lang_items().sized_trait(), + self.tcx.is_lang_item(pred.def_id(), LangItem::Sized), ) else { return; }; diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 32409e13842..8ab324e6601 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1015,6 +1015,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // not eligible. let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); + let tcx = selcx.tcx(); let lang_items = selcx.tcx().lang_items(); if [ lang_items.coroutine_trait(), @@ -1031,7 +1032,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( .contains(&Some(trait_ref.def_id)) { true - } else if lang_items.async_fn_kind_helper() == Some(trait_ref.def_id) { + } else if tcx.is_lang_item(trait_ref.def_id, LangItem::AsyncFnKindHelper) { // FIXME(async_closures): Validity constraints here could be cleaned up. if obligation.predicate.args.type_at(0).is_ty_var() || obligation.predicate.args.type_at(4).is_ty_var() @@ -1043,7 +1044,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( obligation.predicate.args.type_at(0).to_opt_closure_kind().is_some() && obligation.predicate.args.type_at(1).to_opt_closure_kind().is_some() } - } else if lang_items.discriminant_kind_trait() == Some(trait_ref.def_id) { + } else if tcx.is_lang_item(trait_ref.def_id, LangItem::DiscriminantKind) { match self_ty.kind() { ty::Bool | ty::Char @@ -1080,7 +1081,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( | ty::Infer(..) | ty::Error(_) => false, } - } else if lang_items.async_destruct_trait() == Some(trait_ref.def_id) { + } else if tcx.is_lang_item(trait_ref.def_id, LangItem::AsyncDestruct) { match self_ty.kind() { ty::Bool | ty::Char @@ -1116,7 +1117,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( | ty::Infer(_) | ty::Error(_) => false, } - } else if lang_items.pointee_trait() == Some(trait_ref.def_id) { + } else if tcx.is_lang_item(trait_ref.def_id, LangItem::PointeeTrait) { let tail = selcx.tcx().struct_tail_with_normalize( self_ty, |ty| { @@ -1300,15 +1301,15 @@ fn confirm_select_candidate<'cx, 'tcx>( match impl_source { ImplSource::UserDefined(data) => confirm_impl_candidate(selcx, obligation, data), ImplSource::Builtin(BuiltinImplSource::Misc, data) => { - let trait_def_id = obligation.predicate.trait_def_id(selcx.tcx()); - let lang_items = selcx.tcx().lang_items(); - if lang_items.coroutine_trait() == Some(trait_def_id) { + let tcx = selcx.tcx(); + let trait_def_id = obligation.predicate.trait_def_id(tcx); + if tcx.is_lang_item(trait_def_id, LangItem::Coroutine) { confirm_coroutine_candidate(selcx, obligation, data) - } else if lang_items.future_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::Future) { confirm_future_candidate(selcx, obligation, data) - } else if lang_items.iterator_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::Iterator) { confirm_iterator_candidate(selcx, obligation, data) - } else if lang_items.async_iterator_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::AsyncIterator) { confirm_async_iterator_candidate(selcx, obligation, data) } else if selcx.tcx().fn_trait_kind_from_def_id(trait_def_id).is_some() { if obligation.predicate.self_ty().is_closure() @@ -1320,7 +1321,7 @@ fn confirm_select_candidate<'cx, 'tcx>( } } else if selcx.tcx().async_fn_trait_kind_from_def_id(trait_def_id).is_some() { confirm_async_closure_candidate(selcx, obligation, data) - } else if lang_items.async_fn_kind_helper() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::AsyncFnKindHelper) { confirm_async_fn_kind_helper_candidate(selcx, obligation, data) } else { confirm_builtin_candidate(selcx, obligation, data) @@ -1373,10 +1374,9 @@ fn confirm_coroutine_candidate<'cx, 'tcx>( coroutine_sig, ); - let lang_items = tcx.lang_items(); - let ty = if Some(obligation.predicate.def_id) == lang_items.coroutine_return() { + let ty = if tcx.is_lang_item(obligation.predicate.def_id, LangItem::CoroutineReturn) { return_ty - } else if Some(obligation.predicate.def_id) == lang_items.coroutine_yield() { + } else if tcx.is_lang_item(obligation.predicate.def_id, LangItem::CoroutineYield) { yield_ty } else { span_bug!( @@ -1539,21 +1539,20 @@ fn confirm_builtin_candidate<'cx, 'tcx>( ) -> Progress<'tcx> { let tcx = selcx.tcx(); let self_ty = obligation.predicate.self_ty(); - let lang_items = tcx.lang_items(); let item_def_id = obligation.predicate.def_id; let trait_def_id = tcx.trait_of_item(item_def_id).unwrap(); let args = tcx.mk_args(&[self_ty.into()]); - let (term, obligations) = if lang_items.discriminant_kind_trait() == Some(trait_def_id) { + let (term, obligations) = if tcx.is_lang_item(trait_def_id, LangItem::DiscriminantKind) { let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None); assert_eq!(discriminant_def_id, item_def_id); (self_ty.discriminant_ty(tcx).into(), Vec::new()) - } else if lang_items.async_destruct_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::AsyncDestruct) { let destructor_def_id = tcx.associated_item_def_ids(trait_def_id)[0]; assert_eq!(destructor_def_id, item_def_id); (self_ty.async_destructor_ty(tcx).into(), Vec::new()) - } else if lang_items.pointee_trait() == Some(trait_def_id) { + } else if tcx.is_lang_item(trait_def_id, LangItem::PointeeTrait) { let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); assert_eq!(metadata_def_id, item_def_id); diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index 326c68e01db..7dc051e6fe9 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -55,7 +55,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { } ty::Adt(def, _) => { - if Some(def.did()) == tcx.lang_items().manually_drop() { + if def.is_manually_drop() { // `ManuallyDrop` never has a dtor. true } else { diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 6db5fa0e4e5..c53939bfe60 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -67,9 +67,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Other bounds. Consider both in-scope bounds from fn decl // and applicable impls. There is a certain set of precedence rules here. let def_id = obligation.predicate.def_id(); - let lang_items = self.tcx().lang_items(); + let tcx = self.tcx(); - if lang_items.copy_trait() == Some(def_id) { + if tcx.is_lang_item(def_id, LangItem::Copy) { debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty()); // User-defined copy impls are permitted, but only for @@ -79,16 +79,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // For other types, we'll use the builtin rules. let copy_conditions = self.copy_clone_conditions(obligation); self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates); - } else if lang_items.discriminant_kind_trait() == Some(def_id) { + } else if tcx.is_lang_item(def_id, LangItem::DiscriminantKind) { // `DiscriminantKind` is automatically implemented for every type. candidates.vec.push(BuiltinCandidate { has_nested: false }); - } else if lang_items.async_destruct_trait() == Some(def_id) { + } else if tcx.is_lang_item(def_id, LangItem::AsyncDestruct) { // `AsyncDestruct` is automatically implemented for every type. candidates.vec.push(BuiltinCandidate { has_nested: false }); - } else if lang_items.pointee_trait() == Some(def_id) { + } else if tcx.is_lang_item(def_id, LangItem::PointeeTrait) { // `Pointee` is automatically implemented for every type. candidates.vec.push(BuiltinCandidate { has_nested: false }); - } else if lang_items.sized_trait() == Some(def_id) { + } else if tcx.is_lang_item(def_id, LangItem::Sized) { // Sized is never implementable by end-users, it is // always automatically computed. @@ -101,22 +101,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let sized_conditions = self.sized_conditions(obligation); self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates); - } else if lang_items.unsize_trait() == Some(def_id) { + } else if tcx.is_lang_item(def_id, LangItem::Unsize) { self.assemble_candidates_for_unsizing(obligation, &mut candidates); - } else if lang_items.destruct_trait() == Some(def_id) { + } else if tcx.is_lang_item(def_id, LangItem::Destruct) { self.assemble_const_destruct_candidates(obligation, &mut candidates); - } else if lang_items.transmute_trait() == Some(def_id) { + } else if tcx.is_lang_item(def_id, LangItem::TransmuteTrait) { // User-defined transmutability impls are permitted. self.assemble_candidates_from_impls(obligation, &mut candidates); self.assemble_candidates_for_transmutability(obligation, &mut candidates); - } else if lang_items.tuple_trait() == Some(def_id) { + } else if tcx.is_lang_item(def_id, LangItem::Tuple) { self.assemble_candidate_for_tuple(obligation, &mut candidates); - } else if lang_items.pointer_like() == Some(def_id) { + } else if tcx.is_lang_item(def_id, LangItem::PointerLike) { self.assemble_candidate_for_pointer_like(obligation, &mut candidates); - } else if lang_items.fn_ptr_trait() == Some(def_id) { + } else if tcx.is_lang_item(def_id, LangItem::FnPtrTrait) { self.assemble_candidates_for_fn_ptr_trait(obligation, &mut candidates); } else { - if lang_items.clone_trait() == Some(def_id) { + if tcx.is_lang_item(def_id, LangItem::Clone) { // Same builtin conditions as `Copy`, i.e., every type which has builtin support // for `Copy` also has builtin support for `Clone`, and tuples/arrays of `Clone` // types have builtin support for `Clone`. @@ -124,17 +124,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.assemble_builtin_bound_candidates(clone_conditions, &mut candidates); } - if lang_items.coroutine_trait() == Some(def_id) { + if tcx.is_lang_item(def_id, LangItem::Coroutine) { self.assemble_coroutine_candidates(obligation, &mut candidates); - } else if lang_items.future_trait() == Some(def_id) { + } else if tcx.is_lang_item(def_id, LangItem::Future) { self.assemble_future_candidates(obligation, &mut candidates); - } else if lang_items.iterator_trait() == Some(def_id) { + } else if tcx.is_lang_item(def_id, LangItem::Iterator) { self.assemble_iterator_candidates(obligation, &mut candidates); - } else if lang_items.fused_iterator_trait() == Some(def_id) { + } else if tcx.is_lang_item(def_id, LangItem::FusedIterator) { self.assemble_fused_iterator_candidates(obligation, &mut candidates); - } else if lang_items.async_iterator_trait() == Some(def_id) { + } else if tcx.is_lang_item(def_id, LangItem::AsyncIterator) { self.assemble_async_iterator_candidates(obligation, &mut candidates); - } else if lang_items.async_fn_kind_helper() == Some(def_id) { + } else if tcx.is_lang_item(def_id, LangItem::AsyncFnKindHelper) { self.assemble_async_fn_kind_helper_candidates(obligation, &mut candidates); } @@ -239,24 +239,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return Ok(()); } - let all_bounds = stack + let bounds = stack .obligation .param_env .caller_bounds() .iter() .filter(|p| !p.references_error()) - .filter_map(|p| p.as_trait_clause()); - - // Micro-optimization: filter out predicates relating to different traits. - let matching_bounds = - all_bounds.filter(|p| p.def_id() == stack.obligation.predicate.def_id()); + .filter_map(|p| p.as_trait_clause()) + // Micro-optimization: filter out predicates relating to different traits. + .filter(|p| p.def_id() == stack.obligation.predicate.def_id()) + .filter(|p| p.polarity() == stack.obligation.predicate.polarity()); // Keep only those bounds which may apply, and propagate overflow if it occurs. - for bound in matching_bounds { - if bound.skip_binder().polarity != stack.obligation.predicate.skip_binder().polarity { - continue; - } - + for bound in bounds { // FIXME(oli-obk): it is suspicious that we are dropping the constness and // polarity here. let wc = self.where_clause_may_apply(stack, bound.map_bound(|t| t.trait_ref))?; @@ -755,7 +750,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidates.ambiguous = true; } ty::Coroutine(coroutine_def_id, _) - if self.tcx().lang_items().unpin_trait() == Some(def_id) => + if self.tcx().is_lang_item(def_id, LangItem::Unpin) => { match self.tcx().coroutine_movability(coroutine_def_id) { hir::Movability::Static => { diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 749081006f3..074fd487888 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -258,16 +258,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Vec<PredicateObligation<'tcx>> { debug!(?obligation, ?has_nested, "confirm_builtin_candidate"); - let lang_items = self.tcx().lang_items(); + let tcx = self.tcx(); let obligations = if has_nested { let trait_def = obligation.predicate.def_id(); - let conditions = if Some(trait_def) == lang_items.sized_trait() { + let conditions = if tcx.is_lang_item(trait_def, LangItem::Sized) { self.sized_conditions(obligation) - } else if Some(trait_def) == lang_items.copy_trait() { + } else if tcx.is_lang_item(trait_def, LangItem::Copy) { self.copy_clone_conditions(obligation) - } else if Some(trait_def) == lang_items.clone_trait() { + } else if tcx.is_lang_item(trait_def, LangItem::Clone) { self.copy_clone_conditions(obligation) - } else if Some(trait_def) == lang_items.fused_iterator_trait() { + } else if tcx.is_lang_item(trait_def, LangItem::FusedIterator) { self.fused_iterator_conditions(obligation) } else { bug!("unexpected builtin trait {:?}", trait_def) @@ -338,7 +338,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let make_freeze_obl = |ty| { let trait_ref = ty::TraitRef::new( tcx, - tcx.lang_items().freeze_trait().unwrap(), + tcx.require_lang_item(LangItem::Freeze, None), [ty::GenericArg::from(ty)], ); Obligation::with_depth( @@ -1444,7 +1444,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Foreign(_) => {} // `ManuallyDrop` is trivially drop - ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().manually_drop() => {} + ty::Adt(def, _) if def.is_manually_drop() => {} // These types are built-in, so we can fast-track by registering // nested predicates for their constituent type(s) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 212ef2e4b2b..b4019585771 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -32,6 +32,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{Diag, EmissionGuarantee}; use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_hir::LangItem; use rustc_infer::infer::relate::TypeRelation; use rustc_infer::infer::BoundRegionConversionTime; use rustc_infer::infer::BoundRegionConversionTime::HigherRankedType; @@ -2800,19 +2801,18 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let predicates = predicates.instantiate_own(tcx, args); let mut obligations = Vec::with_capacity(predicates.len()); for (index, (predicate, span)) in predicates.into_iter().enumerate() { - let cause = - if Some(parent_trait_pred.def_id()) == tcx.lang_items().coerce_unsized_trait() { - cause.clone() - } else { - cause.clone().derived_cause(parent_trait_pred, |derived| { - ObligationCauseCode::ImplDerived(Box::new(ImplDerivedCause { - derived, - impl_or_alias_def_id: def_id, - impl_def_predicate_index: Some(index), - span, - })) - }) - }; + let cause = if tcx.is_lang_item(parent_trait_pred.def_id(), LangItem::CoerceUnsized) { + cause.clone() + } else { + cause.clone().derived_cause(parent_trait_pred, |derived| { + ObligationCauseCode::ImplDerived(Box::new(ImplDerivedCause { + derived, + impl_or_alias_def_id: def_id, + impl_def_predicate_index: Some(index), + span, + })) + }) + }; let clause = normalize_with_depth_to( self, param_env, diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index e4dcea785d4..094903f61d4 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -1,5 +1,6 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; +use rustc_hir::LangItem; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; use rustc_middle::query::Providers; @@ -34,7 +35,7 @@ fn resolve_instance<'tcx>( let def = if tcx.intrinsic(def_id).is_some() { debug!(" => intrinsic"); ty::InstanceDef::Intrinsic(def_id) - } else if Some(def_id) == tcx.lang_items().drop_in_place_fn() { + } else if tcx.is_lang_item(def_id, LangItem::DropInPlace) { let ty = args.type_at(0); if ty.needs_drop(tcx, param_env) { @@ -57,7 +58,7 @@ fn resolve_instance<'tcx>( debug!(" => trivial drop glue"); ty::InstanceDef::DropGlue(def_id, None) } - } else if Some(def_id) == tcx.lang_items().async_drop_in_place_fn() { + } else if tcx.is_lang_item(def_id, LangItem::AsyncDropInPlace) { let ty = args.type_at(0); if ty.async_drop_glue_morphology(tcx) != AsyncDropGlueMorphology::Noop { @@ -221,8 +222,7 @@ fn resolve_associated_item<'tcx>( ) } traits::ImplSource::Builtin(BuiltinImplSource::Misc, _) => { - let lang_items = tcx.lang_items(); - if Some(trait_ref.def_id) == lang_items.clone_trait() { + if tcx.is_lang_item(trait_ref.def_id, LangItem::Clone) { // FIXME(eddyb) use lang items for methods instead of names. let name = tcx.item_name(trait_item_id); if name == sym::clone { @@ -248,8 +248,8 @@ fn resolve_associated_item<'tcx>( let args = tcx.erase_regions(rcvr_args); Some(ty::Instance::new(trait_item_id, args)) } - } else if Some(trait_ref.def_id) == lang_items.fn_ptr_trait() { - if lang_items.fn_ptr_addr() == Some(trait_item_id) { + } else if tcx.is_lang_item(trait_ref.def_id, LangItem::FnPtrTrait) { + if tcx.is_lang_item(trait_item_id, LangItem::FnPtrAddr) { let self_ty = trait_ref.self_ty(); if !matches!(self_ty.kind(), ty::FnPtr(..)) { return Ok(None); diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 7f0c3df381d..4775a0f8cbb 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -74,6 +74,7 @@ pub use DynKind::*; pub use InferTy::*; pub use RegionKind::*; pub use TyKind::*; +pub use Variance::*; rustc_index::newtype_index! { /// A [De Bruijn index][dbi] is a standard means of representing diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index cae1d13020d..8a6ba87b60e 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -128,7 +128,7 @@ pub fn relate_args_invariantly<I: Interner, R: TypeRelation<I>>( b_arg: I::GenericArgs, ) -> RelateResult<I, I::GenericArgs> { relation.tcx().mk_args_from_iter(iter::zip(a_arg, b_arg).map(|(a, b)| { - relation.relate_with_variance(ty::Variance::Invariant, VarianceDiagInfo::default(), a, b) + relation.relate_with_variance(ty::Invariant, VarianceDiagInfo::default(), a, b) })) } @@ -145,7 +145,7 @@ pub fn relate_args_with_variances<I: Interner, R: TypeRelation<I>>( let mut cached_ty = None; let params = iter::zip(a_arg, b_arg).enumerate().map(|(i, (a, b))| { let variance = variances[i]; - let variance_info = if variance == ty::Variance::Invariant && fetch_ty_for_diag { + let variance_info = if variance == ty::Invariant && fetch_ty_for_diag { let ty = *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, &a_arg)); VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() } @@ -191,7 +191,7 @@ impl<I: Interner> Relate<I> for ty::FnSig<I> { relation.relate(a, b) } else { relation.relate_with_variance( - ty::Variance::Contravariant, + ty::Contravariant, VarianceDiagInfo::default(), a, b, @@ -311,13 +311,13 @@ impl<I: Interner> Relate<I> for ty::ExistentialProjection<I> { })) } else { let term = relation.relate_with_variance( - ty::Variance::Invariant, + ty::Invariant, VarianceDiagInfo::default(), a.term, b.term, )?; let args = relation.relate_with_variance( - ty::Variance::Invariant, + ty::Invariant, VarianceDiagInfo::default(), a.args, b.args, @@ -466,9 +466,9 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>( } let (variance, info) = match a_mutbl { - Mutability::Not => (ty::Variance::Covariant, VarianceDiagInfo::None), + Mutability::Not => (ty::Covariant, VarianceDiagInfo::None), Mutability::Mut => { - (ty::Variance::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 }) + (ty::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 }) } }; @@ -483,9 +483,9 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>( } let (variance, info) = match a_mutbl { - Mutability::Not => (ty::Variance::Covariant, VarianceDiagInfo::None), + Mutability::Not => (ty::Covariant, VarianceDiagInfo::None), Mutability::Mut => { - (ty::Variance::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 }) + (ty::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 }) } }; @@ -612,7 +612,7 @@ pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>( } let args = relation.relate_with_variance( - ty::Variance::Invariant, + ty::Invariant, VarianceDiagInfo::default(), au.args, bu.args, diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 6cf31f2e61e..e0a9674ae5a 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -823,19 +823,29 @@ impl Step for LibcxxVersionTool { fn run(self, builder: &Builder<'_>) -> LibcxxVersion { let out_dir = builder.out.join(self.target.to_string()).join("libcxx-version"); - let _ = fs::remove_dir_all(&out_dir); - t!(fs::create_dir_all(&out_dir)); + let executable = out_dir.join(exe("libcxx-version", self.target)); - let compiler = builder.cxx(self.target).unwrap(); - let mut cmd = Command::new(compiler); + // This is a sanity-check specific step, which means it is frequently called (when using + // CI LLVM), and compiling `src/tools/libcxx-version/main.cpp` at the beginning of the bootstrap + // invocation adds a fair amount of overhead to the process (see https://github.com/rust-lang/rust/issues/126423). + // Therefore, we want to avoid recompiling this file unnecessarily. + if !executable.exists() { + if !out_dir.exists() { + t!(fs::create_dir_all(&out_dir)); + } - let executable = out_dir.join(exe("libcxx-version", self.target)); - cmd.arg("-o").arg(&executable).arg(builder.src.join("src/tools/libcxx-version/main.cpp")); + let compiler = builder.cxx(self.target).unwrap(); + let mut cmd = Command::new(compiler); - builder.run_cmd(&mut cmd); + cmd.arg("-o") + .arg(&executable) + .arg(builder.src.join("src/tools/libcxx-version/main.cpp")); - if !executable.exists() { - panic!("Something went wrong. {} is not present", executable.display()); + builder.run_cmd(&mut cmd); + + if !executable.exists() { + panic!("Something went wrong. {} is not present", executable.display()); + } } let version_output = output(&mut Command::new(executable)); diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index da80f10b7dd..5a0be2948a1 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -128,6 +128,9 @@ pub fn check(build: &mut Build) { eprintln!( "Consider upgrading libstdc++ or disabling the `llvm.download-ci-llvm` option." ); + eprintln!( + "If you choose to upgrade libstdc++, run `x clean` or delete `build/host/libcxx-version` manually after the upgrade." + ); } } tool::LibcxxVersion::Llvm(_) => { diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 4dcbca118ab7f9ffac4728004c983754bc6a04f +Subproject a1f47ec3f7cd076986f1bfcd7061f2e8cb1a726 diff --git a/tests/ui/delegation/macro-inside-list.rs b/tests/ui/delegation/macro-inside-list.rs index 16c74d396ef..d07a4e47dd4 100644 --- a/tests/ui/delegation/macro-inside-list.rs +++ b/tests/ui/delegation/macro-inside-list.rs @@ -14,9 +14,9 @@ struct S(u8); // Macro expansion works inside delegation items. macro_rules! u8 { () => { u8 } } -macro_rules! self_0 { () => { &self.0 } } +macro_rules! self_0 { ($self:ident) => { &$self.0 } } impl Trait for S { - reuse <u8!() as Trait>::{foo, bar} { self_0!() } + reuse <u8!() as Trait>::{foo, bar} { self_0!(self) } } fn main() { diff --git a/tests/ui/delegation/not-supported.stderr b/tests/ui/delegation/not-supported.stderr index 339a8418b33..4ce01fd5d88 100644 --- a/tests/ui/delegation/not-supported.stderr +++ b/tests/ui/delegation/not-supported.stderr @@ -124,6 +124,11 @@ LL | fn opaque_ret() -> impl Trait { unimplemented!() } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the types explicitly +note: in edition 2024, the requirement `!: opaque::Trait` will fail + --> $DIR/not-supported.rs:80:28 + | +LL | fn opaque_ret() -> impl Trait { unimplemented!() } + | ^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:86:5: 86:24>::{synthetic#0}` @@ -154,6 +159,11 @@ LL | pub fn opaque_ret() -> impl Trait { unimplemented!() } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the types explicitly +note: in edition 2024, the requirement `!: opaque::Trait` will fail + --> $DIR/not-supported.rs:72:32 + | +LL | pub fn opaque_ret() -> impl Trait { unimplemented!() } + | ^^^^^^^^^^ error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:89:5: 89:25>::{synthetic#0}` --> $DIR/not-supported.rs:90:24 diff --git a/tests/ui/delegation/self-hygiene.rs b/tests/ui/delegation/self-hygiene.rs new file mode 100644 index 00000000000..dac6c319416 --- /dev/null +++ b/tests/ui/delegation/self-hygiene.rs @@ -0,0 +1,20 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +macro_rules! emit_self { () => { self } } +//~^ ERROR expected value, found module `self` +//~| ERROR expected value, found module `self` + +struct S; +impl S { + fn method(self) { + emit_self!(); + } +} + +fn foo(arg: u8) {} +reuse foo as bar { + emit_self!() +} + +fn main() {} diff --git a/tests/ui/delegation/self-hygiene.stderr b/tests/ui/delegation/self-hygiene.stderr new file mode 100644 index 00000000000..fa64b7d1d7f --- /dev/null +++ b/tests/ui/delegation/self-hygiene.stderr @@ -0,0 +1,31 @@ +error[E0424]: expected value, found module `self` + --> $DIR/self-hygiene.rs:4:34 + | +LL | macro_rules! emit_self { () => { self } } + | ^^^^ `self` value is a keyword only available in methods with a `self` parameter +... +LL | / fn method(self) { +LL | | emit_self!(); + | | ------------ in this macro invocation +LL | | } + | |_____- this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters + | + = note: this error originates in the macro `emit_self` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0424]: expected value, found module `self` + --> $DIR/self-hygiene.rs:4:34 + | +LL | macro_rules! emit_self { () => { self } } + | ^^^^ `self` value is a keyword only available in methods with a `self` parameter +... +LL | / reuse foo as bar { +LL | | emit_self!() + | | ------------ in this macro invocation +LL | | } + | |_- delegation supports a `self` parameter, but a macro invocation can only access identifiers it receives from parameters + | + = note: this error originates in the macro `emit_self` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0424`. diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr index 92c233a0d9c..134fd098b7e 100644 --- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr +++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr @@ -7,6 +7,11 @@ LL | fn m() { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the types explicitly +note: in edition 2024, the requirement `!: Default` will fail + --> $DIR/never-type-fallback-breaking.rs:19:17 + | +LL | true => Default::default(), + | ^^^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default warning: this function depends on never type fallback being `()` @@ -18,6 +23,11 @@ LL | fn q() -> Option<()> { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the types explicitly +note: in edition 2024, the requirement `!: Default` will fail + --> $DIR/never-type-fallback-breaking.rs:34:5 + | +LL | deserialize()?; + | ^^^^^^^^^^^^^ warning: 2 warnings emitted diff --git a/tests/ui/never_type/defaulted-never-note.nofallback.stderr b/tests/ui/never_type/defaulted-never-note.nofallback.stderr index b69b8dda8f1..d88615186dd 100644 --- a/tests/ui/never_type/defaulted-never-note.nofallback.stderr +++ b/tests/ui/never_type/defaulted-never-note.nofallback.stderr @@ -7,6 +7,11 @@ LL | fn smeg() { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the types explicitly +note: in edition 2024, the requirement `!: ImplementedForUnitButNotNever` will fail + --> $DIR/defaulted-never-note.rs:32:9 + | +LL | foo(_x); + | ^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default warning: 1 warning emitted diff --git a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr index 36c82b6d1bf..ec49137ba79 100644 --- a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr +++ b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr @@ -7,6 +7,11 @@ LL | fn def() { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the types explicitly +note: in edition 2024, the requirement `!: Default` will fail + --> $DIR/dependency-on-fallback-to-unit.rs:12:19 + | +LL | false => <_>::default(), + | ^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default warning: this function depends on never type fallback being `()` @@ -18,6 +23,11 @@ LL | fn question_mark() -> Result<(), ()> { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the types explicitly +note: in edition 2024, the requirement `!: Default` will fail + --> $DIR/dependency-on-fallback-to-unit.rs:22:5 + | +LL | deserialize()?; + | ^^^^^^^^^^^^^ warning: 2 warnings emitted diff --git a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr index 5fbdc04ed3b..2a3c5edc218 100644 --- a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr @@ -7,6 +7,11 @@ LL | fn assignment() { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the types explicitly +note: in edition 2024, the requirement `!: UnitDefault` will fail + --> $DIR/diverging-fallback-control-flow.rs:36:13 + | +LL | x = UnitDefault::default(); + | ^^^^^^^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default warning: this function depends on never type fallback being `()` @@ -18,6 +23,11 @@ LL | fn assignment_rev() { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the types explicitly +note: in edition 2024, the requirement `!: UnitDefault` will fail + --> $DIR/diverging-fallback-control-flow.rs:50:13 + | +LL | x = UnitDefault::default(); + | ^^^^^^^^^^^^^^^^^^^^^^ warning: 2 warnings emitted diff --git a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr index d11097323b3..11245cc7aab 100644 --- a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr @@ -7,6 +7,11 @@ LL | fn main() { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the types explicitly +note: in edition 2024, the requirement `!: Test` will fail + --> $DIR/diverging-fallback-no-leak.rs:20:23 + | +LL | unconstrained_arg(return); + | ^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default warning: 1 warning emitted diff --git a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr index 750bcfb7f89..b485c94df4d 100644 --- a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr @@ -7,6 +7,11 @@ LL | fn main() { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the types explicitly +note: in edition 2024, the requirement `!: UnitReturn` will fail + --> $DIR/diverging-fallback-unconstrained-return.rs:39:23 + | +LL | let _ = if true { unconstrained_return() } else { panic!() }; + | ^^^^^^^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default warning: 1 warning emitted diff --git a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr index 9f0b9f6daea..3fb5536dee7 100644 --- a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr +++ b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr @@ -7,6 +7,11 @@ LL | fn main() { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the types explicitly +note: in edition 2024, the requirement `!: Bar` will fail + --> $DIR/fallback-closure-ret.rs:24:5 + | +LL | foo(|| panic!()); + | ^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default warning: 1 warning emitted diff --git a/tests/ui/never_type/impl_trait_fallback.stderr b/tests/ui/never_type/impl_trait_fallback.stderr index 87638940332..4496746e018 100644 --- a/tests/ui/never_type/impl_trait_fallback.stderr +++ b/tests/ui/never_type/impl_trait_fallback.stderr @@ -7,6 +7,11 @@ LL | fn should_ret_unit() -> impl T { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the types explicitly +note: in edition 2024, the requirement `!: T` will fail + --> $DIR/impl_trait_fallback.rs:8:25 + | +LL | fn should_ret_unit() -> impl T { + | ^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default warning: 1 warning emitted |
