diff options
| author | bors <bors@rust-lang.org> | 2024-08-13 15:01:50 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-08-13 15:01:50 +0000 |
| commit | f96e296927cc0c6e9dd611edb943f6349001eca5 (patch) | |
| tree | 76c5e72c0570998ece04f11ac90e09b5d2613abc /compiler/rustc_hir_analysis/src | |
| parent | 00423bb1d85f3513e534abdb26f54a6966e88d47 (diff) | |
| parent | 28af7e09581c3b39cdbf2850df2f157690ab7e56 (diff) | |
| download | rust-f96e296927cc0c6e9dd611edb943f6349001eca5.tar.gz rust-f96e296927cc0c6e9dd611edb943f6349001eca5.zip | |
Auto merge of #17880 - lnicola:sync-from-rust, r=lnicola
minor: sync from downstream
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
41 files changed, 648 insertions, 377 deletions
diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index 2bf14a2461f..53c8586b52a 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -1,15 +1,14 @@ -use crate::errors::AutoDerefReachedRecursionLimit; -use crate::traits; -use crate::traits::query::evaluate_obligation::InferCtxtExt; use rustc_infer::infer::InferCtxt; -use rustc_middle::ty::TypeVisitableExt; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_session::Limit; -use rustc_span::def_id::LocalDefId; -use rustc_span::def_id::LOCAL_CRATE; +use rustc_span::def_id::{LocalDefId, LOCAL_CRATE}; use rustc_span::Span; use rustc_trait_selection::traits::ObligationCtxt; +use crate::errors::AutoDerefReachedRecursionLimit; +use crate::traits; +use crate::traits::query::evaluate_obligation::InferCtxtExt; + #[derive(Copy, Clone, Debug)] pub enum AutoderefKind { /// A true pointer type, such as `&T` and `*mut T`. diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 27db5418165..2e778fd3759 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1,12 +1,9 @@ -use crate::check::intrinsicck::InlineAsmCtxt; +use std::cell::LazyCell; +use std::ops::ControlFlow; -use super::compare_impl_item::check_type_bounds; -use super::compare_impl_item::{compare_impl_method, compare_impl_ty}; -use super::*; -use rustc_attr as attr; use rustc_data_structures::unord::{UnordMap, UnordSet}; -use rustc_errors::{codes::*, MultiSpan}; -use rustc_hir as hir; +use rustc_errors::codes::*; +use rustc_errors::MultiSpan; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::Node; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; @@ -19,9 +16,9 @@ use rustc_middle::ty::error::TypeErrorToStringExt; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt}; -use rustc_middle::ty::GenericArgKind; use rustc_middle::ty::{ - AdtDef, ParamEnv, RegionKind, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, + AdtDef, GenericArgKind, ParamEnv, RegionKind, TypeSuperVisitable, TypeVisitable, + TypeVisitableExt, }; use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; use rustc_target::abi::FieldIdx; @@ -30,9 +27,11 @@ use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::traits; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_type_ir::fold::TypeFoldable; +use {rustc_attr as attr, rustc_hir as hir}; -use std::cell::LazyCell; -use std::ops::ControlFlow; +use super::compare_impl_item::{check_type_bounds, compare_impl_method, compare_impl_ty}; +use super::*; +use crate::check::intrinsicck::InlineAsmCtxt; pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) { match tcx.sess.target.is_abi_supported(abi) { diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index c99f13468e2..35577613800 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1,24 +1,24 @@ -use super::potentially_plural_count; -use crate::errors::{LifetimesOrBoundsMismatchOnTrait, MethodShouldReturnFuture}; use core::ops::ControlFlow; +use std::borrow::Cow; +use std::iter; + use hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; -use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed}; +use rustc_errors::codes::*; +use rustc_errors::{pluralize, struct_span_code_err, Applicability, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::intravisit; -use rustc_hir::{GenericParamKind, ImplItemKind}; +use rustc_hir::{intravisit, GenericParamKind, ImplItemKind}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::util; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::util::ExplicitSelf; -use rustc_middle::ty::Upcast; use rustc_middle::ty::{ - self, GenericArgs, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, + self, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeFolder, + TypeSuperFoldable, TypeVisitableExt, Upcast, }; -use rustc_middle::ty::{GenericParamDefKind, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_span::Span; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; @@ -28,8 +28,9 @@ use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::{ self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, Reveal, }; -use std::borrow::Cow; -use std::iter; + +use super::potentially_plural_count; +use crate::errors::{LifetimesOrBoundsMismatchOnTrait, MethodShouldReturnFuture}; mod refine; @@ -1116,7 +1117,7 @@ fn check_region_bounds_on_impl_item<'tcx>( .dcx() .create_err(LifetimesOrBoundsMismatchOnTrait { span, - item_kind: assoc_item_kind_str(&impl_m), + item_kind: impl_m.descr(), ident: impl_m.ident(tcx), generics_span, bounds_span, @@ -1293,7 +1294,7 @@ fn compare_number_of_generics<'tcx>( ("const", trait_own_counts.consts, impl_own_counts.consts), ]; - let item_kind = assoc_item_kind_str(&impl_); + let item_kind = impl_.descr(); let mut err_occurred = None; for (kind, trait_count, impl_count) in matchings { @@ -1675,7 +1676,7 @@ fn compare_generic_param_kinds<'tcx>( param_impl_span, E0053, "{} `{}` has an incompatible generic parameter for trait `{}`", - assoc_item_kind_str(&impl_item), + impl_item.descr(), trait_item.name, &tcx.def_path_str(tcx.parent(trait_item.def_id)) ); @@ -2248,14 +2249,6 @@ fn param_env_with_gat_bounds<'tcx>( ty::ParamEnv::new(tcx.mk_clauses(&predicates), Reveal::UserFacing) } -fn assoc_item_kind_str(impl_item: &ty::AssocItem) -> &'static str { - match impl_item.kind { - ty::AssocKind::Const => "const", - ty::AssocKind::Fn => "method", - ty::AssocKind::Type => "type", - } -} - /// Manually check here that `async fn foo()` wasn't matched against `fn foo()`, /// and extract a better error if so. fn try_report_async_mismatch<'tcx>( diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index ad3324f79e2..80daaa60324 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -1,7 +1,8 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_infer::infer::{outlives::env::OutlivesEnvironment, TyCtxtInferExt}; +use rustc_infer::infer::outlives::env::OutlivesEnvironment; +use rustc_infer::infer::TyCtxtInferExt; use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT_REACHABLE}; use rustc_middle::span_bug; use rustc_middle::traits::{ObligationCause, Reveal}; @@ -10,9 +11,8 @@ use rustc_middle::ty::{ }; use rustc_span::Span; use rustc_trait_selection::regions::InferCtxtRegionExt; -use rustc_trait_selection::traits::{ - elaborate, normalize_param_env_or_error, outlives_bounds::InferCtxtExt, ObligationCtxt, -}; +use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt; +use rustc_trait_selection::traits::{elaborate, normalize_param_env_or_error, ObligationCtxt}; /// Check that an implementation does not refine an RPITIT from a trait method signature. pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>( diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index 06ec01484a4..d173915e480 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -3,13 +3,13 @@ // We don't do any drop checking during hir typeck. use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed}; +use rustc_errors::codes::*; +use rustc_errors::{struct_span_code_err, ErrorGuaranteed}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; use rustc_infer::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::util::CheckRegions; -use rustc_middle::ty::{self, TyCtxt}; -use rustc_middle::ty::{GenericArgsRef, Ty}; +use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt}; use rustc_trait_selection::regions::InferCtxtRegionExt; use rustc_trait_selection::traits::{self, ObligationCtxt}; diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs index e4d4b7df24e..1f724580564 100644 --- a/compiler/rustc_hir_analysis/src/check/entry.rs +++ b/compiler/rustc_hir_analysis/src/check/entry.rs @@ -1,3 +1,5 @@ +use std::ops::Not; + use rustc_hir as hir; use rustc_hir::Node; use rustc_infer::infer::TyCtxtInferExt; @@ -5,13 +7,12 @@ use rustc_middle::span_bug; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::config::EntryFnType; use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; -use rustc_span::{symbol::sym, Span}; +use rustc_span::symbol::sym; +use rustc_span::Span; use rustc_target::spec::abi::Abi; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode}; -use std::ops::Not; - use super::check_function_signature; use crate::errors; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 6282499883b..4b45ced30c5 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -1,13 +1,8 @@ //! Type-checking for the rust-intrinsic and platform-intrinsic //! intrinsics that the compiler exposes. -use crate::check::check_function_signature; -use crate::errors::{ - UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction, - WrongNumberOfGenericArgumentsToIntrinsic, -}; - -use rustc_errors::{codes::*, struct_span_code_err, DiagMessage}; +use rustc_errors::codes::*; +use rustc_errors::{struct_span_code_err, DiagMessage}; use rustc_hir as hir; use rustc_middle::bug; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; @@ -17,6 +12,12 @@ use rustc_span::symbol::sym; use rustc_span::{Span, Symbol}; use rustc_target::spec::abi::Abi; +use crate::check::check_function_signature; +use crate::errors::{ + UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction, + WrongNumberOfGenericArgumentsToIntrinsic, +}; + fn equate_intrinsic_type<'tcx>( tcx: TyCtxt<'tcx>, span: Span, @@ -119,6 +120,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) - | sym::type_id | sym::likely | sym::unlikely + | sym::select_unpredictable | sym::ptr_guaranteed_cmp | sym::minnumf16 | sym::minnumf32 @@ -487,6 +489,7 @@ pub fn check_intrinsic_type( sym::assume => (0, 0, vec![tcx.types.bool], tcx.types.unit), sym::likely => (0, 0, vec![tcx.types.bool], tcx.types.bool), sym::unlikely => (0, 0, vec![tcx.types.bool], tcx.types.bool), + sym::select_unpredictable => (1, 0, vec![tcx.types.bool, param(0), param(0)], param(0)), sym::read_via_copy => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)), sym::write_via_move => { diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 2e965c59ebb..79ecdee4486 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -1,8 +1,10 @@ +use std::assert_matches::debug_assert_matches; + use rustc_ast::InlineAsmTemplatePiece; use rustc_data_structures::fx::FxIndexSet; 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_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; use rustc_span::Symbol; @@ -455,32 +457,22 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ); } } - // No special checking is needed for these: - // - Typeck has checked that Const operands are integers. - // - AST lowering guarantees that SymStatic points to a static. - hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::SymStatic { .. } => {} - // Check that sym actually points to a function. Later passes - // depend on this. + // Typeck has checked that Const operands are integers. + hir::InlineAsmOperand::Const { anon_const } => { + debug_assert_matches!( + self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(), + ty::Error(_) | ty::Int(_) | ty::Uint(_) + ); + } + // Typeck has checked that SymFn refers to a function. hir::InlineAsmOperand::SymFn { anon_const } => { - let ty = self.tcx.type_of(anon_const.def_id).instantiate_identity(); - match ty.kind() { - ty::Never | ty::Error(_) => {} - ty::FnDef(..) => {} - _ => { - self.tcx - .dcx() - .struct_span_err(*op_sp, "invalid `sym` operand") - .with_span_label( - self.tcx.def_span(anon_const.def_id), - format!("is {} `{}`", ty.kind().article(), ty), - ) - .with_help( - "`sym` operands must refer to either a function or a static", - ) - .emit(); - } - }; + debug_assert_matches!( + self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(), + ty::Error(_) | ty::FnDef(..) + ); } + // AST lowering guarantees that SymStatic points to a static. + hir::InlineAsmOperand::SymStatic { .. } => {} // No special checking is needed for labels. hir::InlineAsmOperand::Label { .. } => {} } diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 4c230ad84de..678b8c89a50 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -72,13 +72,11 @@ pub mod intrinsicck; mod region; pub mod wfcheck; -pub use check::check_abi; - use std::num::NonZero; +pub use check::check_abi; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; -use rustc_errors::ErrorGuaranteed; -use rustc_errors::{pluralize, struct_span_code_err, Diag}; +use rustc_errors::{pluralize, struct_span_code_err, Diag, ErrorGuaranteed}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_index::bit_set::BitSet; @@ -87,12 +85,12 @@ use rustc_infer::infer::{self, TyCtxtInferExt as _}; use rustc_infer::traits::ObligationCause; use rustc_middle::query::Providers; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::ty::{GenericArgs, GenericArgsRef}; +use rustc_middle::ty::{self, GenericArgs, GenericArgsRef, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_session::parse::feature_err; +use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::symbol::{kw, sym, Ident}; -use rustc_span::{def_id::CRATE_DEF_ID, BytePos, Span, Symbol, DUMMY_SP}; +use rustc_span::{BytePos, Span, Symbol, DUMMY_SP}; use rustc_target::abi::VariantIdx; use rustc_target::spec::abi::Abi; use rustc_trait_selection::error_reporting::infer::ObligationCauseExt as _; @@ -100,11 +98,9 @@ use rustc_trait_selection::error_reporting::traits::suggestions::ReturnsVisitor; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::traits::ObligationCtxt; -use crate::errors; -use crate::require_c_abi_if_c_variadic; - use self::compare_impl_item::collect_return_position_impl_trait_in_trait_tys; use self::region::region_scope_tree; +use crate::{errors, require_c_abi_if_c_variadic}; pub fn provide(providers: &mut Providers) { wfcheck::provide(providers); diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 2b5efd3b2f6..bc6641c688c 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -6,6 +6,8 @@ //! //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html +use std::mem; + use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -19,8 +21,6 @@ use rustc_span::source_map; use super::errs::{maybe_expr_static_mut, maybe_stmt_static_mut}; -use std::mem; - #[derive(Debug, Copy, Clone)] pub struct Context { /// The scope that contains any new variables declared, plus its depth in diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 456dc4e4e07..a9f8630741a 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1,14 +1,10 @@ -use crate::autoderef::Autoderef; -use crate::collect::CollectItemTypesVisitor; -use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter}; -use crate::errors; -use crate::fluent_generated as fluent; +use std::cell::LazyCell; +use std::ops::{ControlFlow, Deref}; use hir::intravisit::{self, Visitor}; -use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; -use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed}; -use rustc_hir as hir; +use rustc_errors::codes::*; +use rustc_errors::{pluralize, struct_span_code_err, Applicability, ErrorGuaranteed}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::lang_items::LangItem; @@ -20,10 +16,9 @@ use rustc_middle::query::Providers; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ - self, AdtKind, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, - TypeVisitable, TypeVisitableExt, TypeVisitor, Upcast, + self, AdtKind, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, + TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, Upcast, }; -use rustc_middle::ty::{GenericArgKind, GenericArgs}; use rustc_middle::{bug, span_bug}; use rustc_session::parse::feature_err; use rustc_span::symbol::{sym, Ident}; @@ -41,9 +36,12 @@ use rustc_trait_selection::traits::{ }; use rustc_type_ir::solve::NoSolution; use rustc_type_ir::TypeFlags; +use {rustc_ast as ast, rustc_hir as hir}; -use std::cell::LazyCell; -use std::ops::{ControlFlow, Deref}; +use crate::autoderef::Autoderef; +use crate::collect::CollectItemTypesVisitor; +use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter}; +use crate::{errors, fluent_generated as fluent}; pub(super) struct WfCheckingCtxt<'a, 'tcx> { pub(super) ocx: ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>>, @@ -1278,7 +1276,7 @@ fn check_item_type( UnsizedHandling::Forbid => true, UnsizedHandling::Allow => false, UnsizedHandling::AllowIfForeignTail => { - let tail = tcx.struct_tail_erasing_lifetimes(item_ty, wfcx.param_env); + let tail = tcx.struct_tail_for_codegen(item_ty, wfcx.param_env); !matches!(tail.kind(), ty::Foreign(_)) } }; diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index b35ee270fef..fecd78bc38f 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -1,7 +1,8 @@ //! Check properties that are required by built-in traits and set //! up data structures required by type-checking/codegen. -use crate::errors; +use std::assert_matches::assert_matches; +use std::collections::BTreeMap; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{ErrorGuaranteed, MultiSpan}; @@ -10,8 +11,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_hir::ItemKind; use rustc_infer::infer::outlives::env::OutlivesEnvironment; -use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::infer::{self, RegionResolutionError}; +use rustc_infer::infer::{self, RegionResolutionError, TyCtxtInferExt}; use rustc_infer::traits::Obligation; use rustc_middle::ty::adjustment::CoerceUnsizedInfo; use rustc_middle::ty::print::PrintTraitRefExt as _; @@ -22,9 +22,9 @@ use rustc_trait_selection::traits::misc::{ type_allowed_to_implement_const_param_ty, type_allowed_to_implement_copy, ConstParamTyImplementationError, CopyImplementationError, InfringingFieldsReason, }; -use rustc_trait_selection::traits::ObligationCtxt; -use rustc_trait_selection::traits::{self, ObligationCause}; -use std::collections::BTreeMap; +use rustc_trait_selection::traits::{self, ObligationCause, ObligationCtxt}; + +use crate::errors; pub(super) fn check_trait<'tcx>( tcx: TyCtxt<'tcx>, @@ -130,7 +130,7 @@ fn visit_implementation_of_const_param_ty( checker: &Checker<'_>, kind: LangItem, ) -> Result<(), ErrorGuaranteed> { - assert!(matches!(kind, LangItem::ConstParamTy | LangItem::UnsizedConstParamTy)); + assert_matches!(kind, LangItem::ConstParamTy | LangItem::UnsizedConstParamTy); let tcx = checker.tcx; let header = checker.impl_header; diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index 3aef29f4ae4..cd5cc33d65a 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -1,6 +1,6 @@ -use rustc_data_structures::fx::IndexEntry; -use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; -use rustc_errors::{codes::*, struct_span_code_err}; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap, IndexEntry}; +use rustc_errors::codes::*; +use rustc_errors::struct_span_code_err; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index e9961d3ad08..8e4da90ca26 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -5,8 +5,8 @@ // done by the orphan and overlap modules. Then we build up various // mappings. That mapping code resides here. -use crate::errors; -use rustc_errors::{codes::*, struct_span_code_err}; +use rustc_errors::codes::*; +use rustc_errors::struct_span_code_err; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::LangItem; use rustc_middle::query::Providers; @@ -14,6 +14,8 @@ use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_session::parse::feature_err; use rustc_span::{sym, ErrorGuaranteed}; +use crate::errors; + mod builtin; mod inherent_impls; mod inherent_impls_overlap; diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index f2804ce31fa..dcd0e3111a4 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -1,19 +1,21 @@ //! Orphan checker: every impl either implements a trait defined in this //! crate or pertains to a type defined in this crate. -use crate::errors; - use rustc_data_structures::fx::FxIndexSet; use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_lint_defs::builtin::UNCOVERED_PARAM_IN_PROJECTION; -use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::ty::{TypeFoldable, TypeFolder, TypeSuperFoldable}; -use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; +use rustc_middle::ty::{ + self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, + TypeVisitable, TypeVisitableExt, TypeVisitor, +}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::{DefId, LocalDefId}; -use rustc_trait_selection::traits::{self, IsFirstInputType, UncoveredTyParams}; -use rustc_trait_selection::traits::{OrphanCheckErr, OrphanCheckMode}; +use rustc_trait_selection::traits::{ + self, IsFirstInputType, OrphanCheckErr, OrphanCheckMode, UncoveredTyParams, +}; + +use crate::errors; #[instrument(level = "debug", skip(tcx))] pub(crate) fn orphan_check_impl( diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs index 5fe21e9b822..7513f680271 100644 --- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs +++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs @@ -1,10 +1,12 @@ //! Unsafety checker: every impl either implements a trait defined in this //! crate or pertains to a type defined in this crate. -use rustc_errors::{codes::*, struct_span_code_err}; +use rustc_errors::codes::*; +use rustc_errors::struct_span_code_err; use rustc_hir::Safety; use rustc_middle::ty::print::PrintTraitRefExt as _; -use rustc_middle::ty::{ImplPolarity::*, ImplTraitHeader, TraitDef, TyCtxt}; +use rustc_middle::ty::ImplPolarity::*; +use rustc_middle::ty::{ImplTraitHeader, TraitDef, TyCtxt}; use rustc_span::def_id::LocalDefId; use rustc_span::ErrorGuaranteed; diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 565351268c9..91fa066ec6a 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -14,6 +14,10 @@ //! At present, however, we do run collection across all items in the //! crate as a kind of pass. This should eventually be factored away. +use std::cell::Cell; +use std::iter; +use std::ops::Bound; + use rustc_ast::Recovered; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; @@ -24,8 +28,7 @@ use rustc_errors::{ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, walk_generics, Visitor}; -use rustc_hir::{self as hir}; -use rustc_hir::{GenericParamKind, Node}; +use rustc_hir::{self as hir, GenericParamKind, Node}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::ObligationCause; use rustc_middle::hir::nested_filter; @@ -39,9 +42,6 @@ use rustc_target::spec::abi; use rustc_trait_selection::error_reporting::traits::suggestions::NextTypeParamName; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::ObligationCtxt; -use std::cell::Cell; -use std::iter; -use std::ops::Bound; use crate::check::intrinsic::intrinsic_operation_unsafety; use crate::errors; @@ -67,6 +67,7 @@ pub fn provide(providers: &mut Providers) { item_super_predicates: item_bounds::item_super_predicates, explicit_item_super_predicates: item_bounds::explicit_item_super_predicates, item_non_self_assumptions: item_bounds::item_non_self_assumptions, + impl_super_outlives: item_bounds::impl_super_outlives, generics_of: generics_of::generics_of, predicates_of: predicates_of::predicates_of, predicates_defined_on, @@ -1207,25 +1208,29 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> { fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { let item = tcx.hir().expect_item(def_id); - let (is_auto, safety, items) = match item.kind { + let (is_alias, is_auto, safety, items) = match item.kind { hir::ItemKind::Trait(is_auto, safety, .., items) => { - (is_auto == hir::IsAuto::Yes, safety, items) + (false, is_auto == hir::IsAuto::Yes, safety, items) } - hir::ItemKind::TraitAlias(..) => (false, hir::Safety::Safe, &[][..]), + hir::ItemKind::TraitAlias(..) => (true, false, hir::Safety::Safe, &[][..]), _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"), }; - let constness = if tcx.has_attr(def_id, sym::const_trait) { + // Only regular traits can be const. + let constness = if !is_alias && tcx.has_attr(def_id, sym::const_trait) { hir::Constness::Const } else { hir::Constness::NotConst }; + let paren_sugar = tcx.has_attr(def_id, sym::rustc_paren_sugar); if paren_sugar && !tcx.features().unboxed_closures { tcx.dcx().emit_err(errors::ParenSugarAttribute { span: item.span }); } - let is_marker = tcx.has_attr(def_id, sym::marker); + // Only regular traits can be marker. + let is_marker = !is_alias && tcx.has_attr(def_id, sym::marker); + let rustc_coinductive = tcx.has_attr(def_id, sym::rustc_coinductive); let is_fundamental = tcx.has_attr(def_id, sym::fundamental); @@ -1695,6 +1700,8 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTrai trait_ref: ty::EarlyBinder::bind(trait_ref), safety: impl_.safety, polarity: polarity_of_impl(tcx, def_id, impl_, item.span), + do_not_recommend: tcx.features().do_not_recommend + && tcx.has_attrs_with_path(def_id, &[sym::diagnostic, sym::do_not_recommend]), } }) } diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 690423421b9..28d6cab4b43 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -1,10 +1,8 @@ +use std::assert_matches::assert_matches; use std::ops::ControlFlow; -use crate::middle::resolve_bound_vars as rbv; -use hir::{ - intravisit::{self, Visitor}, - GenericParamKind, HirId, Node, -}; +use hir::intravisit::{self, Visitor}; +use hir::{GenericParamKind, HirId, Node}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; @@ -13,6 +11,9 @@ use rustc_session::lint; use rustc_span::symbol::{kw, Symbol}; use rustc_span::Span; +use crate::delegation::inherit_generics_for_delegation_item; +use crate::middle::resolve_bound_vars as rbv; + #[instrument(level = "debug", skip(tcx), ret)] pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { use rustc_hir::*; @@ -207,9 +208,9 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { .. }) => { if in_trait { - assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn)) + assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn); } else { - assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn)) + assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn); } Some(fn_def_id.to_def_id()) } @@ -218,15 +219,25 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { .. }) => { if in_assoc_ty { - assert!(matches!(tcx.def_kind(parent), DefKind::AssocTy)); + assert_matches!(tcx.def_kind(parent), DefKind::AssocTy); } else { - assert!(matches!(tcx.def_kind(parent), DefKind::TyAlias)); + assert_matches!(tcx.def_kind(parent), DefKind::TyAlias); } debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent); // Opaque types are always nested within another item, and // inherit the generics of the item. Some(parent.to_def_id()) } + ItemKind::Fn(sig, _, _) => { + // For a delegation item inherit generics from callee. + if let Some(sig_id) = sig.decl.opt_delegation_sig_id() + && let Some(generics) = + inherit_generics_for_delegation_item(tcx, def_id, sig_id) + { + return generics; + } + None + } _ => None, }, _ => None, @@ -328,8 +339,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { if default.is_some() { match allow_defaults { Defaults::Allowed => {} - Defaults::FutureCompatDisallowed - if tcx.features().default_type_parameter_fallback => {} Defaults::FutureCompatDisallowed => { tcx.node_span_lint( lint::builtin::INVALID_TYPE_PARAM_DEFAULT, diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index c03e074c80b..ec48c781c0e 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -1,15 +1,17 @@ -use super::ItemCtxt; -use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter}; use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_infer::traits::util; -use rustc_middle::ty::GenericArgs; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::{ + self, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, +}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::Span; use rustc_type_ir::Upcast; +use super::ItemCtxt; +use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter}; + /// For associated types we include both bounds written on the type /// (`type X: Trait`) and predicates from the trait: `where Self::X: Trait`. /// @@ -210,6 +212,8 @@ pub(super) fn item_super_predicates( }) } +/// This exists as an optimization to compute only the item bounds of the item +/// that are not `Self` bounds. pub(super) fn item_non_self_assumptions( tcx: TyCtxt<'_>, def_id: DefId, @@ -224,6 +228,25 @@ pub(super) fn item_non_self_assumptions( } } +/// This exists as an optimization to compute only the supertraits of this impl's +/// trait that are outlives bounds. +pub(super) fn impl_super_outlives( + tcx: TyCtxt<'_>, + def_id: DefId, +) -> ty::EarlyBinder<'_, ty::Clauses<'_>> { + tcx.impl_trait_header(def_id).expect("expected an impl of trait").trait_ref.map_bound( + |trait_ref| { + let clause: ty::Clause<'_> = trait_ref.upcast(tcx); + tcx.mk_clauses_from_iter(util::elaborate(tcx, [clause]).filter(|clause| { + matches!( + clause.kind().skip_binder(), + ty::ClauseKind::TypeOutlives(_) | ty::ClauseKind::RegionOutlives(_) + ) + })) + }, + ) +} + struct AssocTyToOpaque<'tcx> { tcx: TyCtxt<'tcx>, fn_def_id: DefId, diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 9e430c83e20..6ac4802b195 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -1,19 +1,22 @@ -use crate::bounds::Bounds; -use crate::collect::ItemCtxt; -use crate::constrained_generic_params as cgp; -use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter, RegionInferReason}; +use std::assert_matches::assert_matches; + use hir::{HirId, Node}; use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; -use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::ty::{GenericPredicates, ImplTraitInTraitData, Upcast}; +use rustc_middle::ty::{self, GenericPredicates, ImplTraitInTraitData, Ty, TyCtxt, Upcast}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Ident; use rustc_span::{Span, DUMMY_SP}; +use crate::bounds::Bounds; +use crate::collect::ItemCtxt; +use crate::constrained_generic_params as cgp; +use crate::delegation::inherit_predicates_for_delegation_item; +use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter, RegionInferReason}; + /// Returns a list of all type predicates (explicit and implicit) for the definition with /// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus /// `Self: Trait` predicates for traits. @@ -143,6 +146,16 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen ItemKind::Trait(_, _, _, self_bounds, ..) | ItemKind::TraitAlias(_, self_bounds) => { is_trait = Some(self_bounds); } + + ItemKind::Fn(sig, _, _) => { + // For a delegation item inherit predicates from callee. + if let Some(sig_id) = sig.decl.opt_delegation_sig_id() + && let Some(predicates) = + inherit_predicates_for_delegation_item(tcx, def_id, sig_id) + { + return predicates; + } + } _ => {} } }; @@ -590,7 +603,7 @@ pub(super) fn implied_predicates_with_filter( let Some(trait_def_id) = trait_def_id.as_local() else { // if `assoc_name` is None, then the query should've been redirected to an // external provider - assert!(matches!(filter, PredicateFilter::SelfThatDefines(_))); + assert_matches!(filter, PredicateFilter::SelfThatDefines(_)); return tcx.explicit_super_predicates_of(trait_def_id); }; diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 02ea95852f0..e11d3c9c48b 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -7,6 +7,8 @@ //! is also responsible for assigning their semantics to implicit lifetimes in trait objects. use core::ops::ControlFlow; +use std::fmt; + use rustc_ast::visit::walk_list; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_hir as hir; @@ -23,7 +25,6 @@ use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; -use std::fmt; use crate::errors; diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 9affd654366..8cb4ba6c669 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -1,4 +1,5 @@ use core::ops::ControlFlow; + use rustc_errors::{Applicability, StashKey}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -6,17 +7,15 @@ use rustc_hir::HirId; use rustc_middle::query::plumbing::CyclePlaceholder; use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::util::IntTypeExt; -use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, Article, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Ident; use rustc_span::{Span, DUMMY_SP}; +use super::{bad_placeholder, ItemCtxt}; use crate::errors::TypeofReservedKeywordUsed; use crate::hir_ty_lowering::HirTyLowerer; -use super::bad_placeholder; -use super::ItemCtxt; - mod opaque; fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { @@ -35,6 +34,20 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { let parent_node_id = tcx.parent_hir_id(hir_id); let parent_node = tcx.hir_node(parent_node_id); + let find_sym_fn = |&(op, op_sp)| match op { + hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == hir_id => { + Some((anon_const, op_sp)) + } + _ => None, + }; + + let find_const = |&(op, op_sp)| match op { + hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == hir_id => { + Some((anon_const, op_sp)) + } + _ => None, + }; + match parent_node { // Anon consts "inside" the type system. Node::ConstArg(&ConstArg { @@ -46,13 +59,51 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { // Anon consts outside the type system. Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) - if asm.operands.iter().any(|(op, _op_sp)| match op { - hir::InlineAsmOperand::Const { anon_const } - | hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id, - _ => false, - }) => + if let Some((anon_const, op_sp)) = asm.operands.iter().find_map(find_sym_fn) => { - tcx.typeck(def_id).node_type(hir_id) + let ty = tcx.typeck(def_id).node_type(hir_id); + + match ty.kind() { + ty::Error(_) => ty, + ty::FnDef(..) => ty, + _ => { + let guar = tcx + .dcx() + .struct_span_err(op_sp, "invalid `sym` operand") + .with_span_label( + tcx.def_span(anon_const.def_id), + format!("is {} `{}`", ty.kind().article(), ty), + ) + .with_help("`sym` operands must refer to either a function or a static") + .emit(); + + Ty::new_error(tcx, guar) + } + } + } + Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) + | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) + if let Some((anon_const, op_sp)) = asm.operands.iter().find_map(find_const) => + { + let ty = tcx.typeck(def_id).node_type(hir_id); + + match ty.kind() { + ty::Error(_) => ty, + ty::Int(_) | ty::Uint(_) => ty, + _ => { + let guar = tcx + .dcx() + .struct_span_err(op_sp, "invalid type for `const` operand") + .with_span_label( + tcx.def_span(anon_const.def_id), + format!("is {} `{}`", ty.kind().article(), ty), + ) + .with_help("`const` operands must be of an integer type") + .emit(); + + Ty::new_error(tcx, guar) + } + } } Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => { tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx) diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs new file mode 100644 index 00000000000..20aaa43219f --- /dev/null +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -0,0 +1,261 @@ +use std::assert_matches::debug_assert_matches; + +use rustc_data_structures::fx::FxHashMap; +use rustc_hir::def::DefKind; +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_span::ErrorGuaranteed; +use rustc_type_ir::visit::TypeVisitableExt; + +type RemapTable = FxHashMap<u32, u32>; + +struct ParamIndexRemapper<'tcx> { + tcx: TyCtxt<'tcx>, + remap_table: RemapTable, +} + +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamIndexRemapper<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + if !ty.has_param() { + return ty; + } + + if let ty::Param(param) = ty.kind() + && let Some(index) = self.remap_table.get(¶m.index) + { + return Ty::new_param(self.tcx, *index, param.name); + } + ty.super_fold_with(self) + } + + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + if let ty::ReEarlyParam(param) = r.kind() + && let Some(index) = self.remap_table.get(¶m.index).copied() + { + return ty::Region::new_early_param( + self.tcx, + ty::EarlyParamRegion { index, name: param.name }, + ); + } + r + } + + fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { + if let ty::ConstKind::Param(param) = ct.kind() + && let Some(idx) = self.remap_table.get(¶m.index) + { + let param = ty::ParamConst::new(*idx, param.name); + return ty::Const::new_param(self.tcx, param); + } + ct.super_fold_with(self) + } +} + +#[derive(Clone, Copy, Debug, PartialEq)] +enum FnKind { + Free, + AssocInherentImpl, + AssocTrait, + AssocTraitImpl, +} + +fn fn_kind<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> FnKind { + debug_assert_matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn); + + let parent = tcx.parent(def_id); + match tcx.def_kind(parent) { + DefKind::Trait => FnKind::AssocTrait, + DefKind::Impl { of_trait: true } => FnKind::AssocTraitImpl, + DefKind::Impl { of_trait: false } => FnKind::AssocInherentImpl, + _ => FnKind::Free, + } +} + +fn create_generic_args<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + sig_id: DefId, +) -> ty::GenericArgsRef<'tcx> { + let caller_generics = tcx.generics_of(def_id); + let callee_generics = tcx.generics_of(sig_id); + + let caller_kind = fn_kind(tcx, def_id.into()); + let callee_kind = fn_kind(tcx, sig_id); + // FIXME(fn_delegation): Support generics on associated delegation items. + // Error will be reported in `check_constraints`. + match (caller_kind, callee_kind) { + (FnKind::Free, _) => { + // Lifetime parameters must be declared before type and const parameters. + // Therefore, When delegating from a free function to a associated function, + // generic parameters need to be reordered: + // + // trait Trait<'a, A> { + // fn foo<'b, B>(...) {...} + // } + // + // reuse Trait::foo; + // desugaring: + // fn foo<'a, 'b, This: Trait<'a, A>, A, B>(...) { + // Trait::foo(...) + // } + let mut remap_table = RemapTable::default(); + for caller_param in &caller_generics.own_params { + let callee_index = + callee_generics.param_def_id_to_index(tcx, caller_param.def_id).unwrap(); + remap_table.insert(callee_index, caller_param.index); + } + let mut folder = ParamIndexRemapper { tcx, remap_table }; + ty::GenericArgs::identity_for_item(tcx, sig_id).fold_with(&mut folder) + } + // FIXME(fn_delegation): Only `Self` param supported here. + (FnKind::AssocTraitImpl, FnKind::AssocTrait) + | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => { + let parent = tcx.parent(def_id.into()); + let self_ty = tcx.type_of(parent).instantiate_identity(); + let generic_self_ty = ty::GenericArg::from(self_ty); + tcx.mk_args_from_iter(std::iter::once(generic_self_ty)) + } + _ => ty::GenericArgs::identity_for_item(tcx, sig_id), + } +} + +pub(crate) fn inherit_generics_for_delegation_item<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + sig_id: DefId, +) -> Option<ty::Generics> { + // FIXME(fn_delegation): Support generics on associated delegation items. + // Error will be reported in `check_constraints`. + if fn_kind(tcx, def_id.into()) != FnKind::Free { + return None; + } + + let mut own_params = vec![]; + + let callee_generics = tcx.generics_of(sig_id); + if let Some(parent_sig_id) = callee_generics.parent { + let parent_sig_generics = tcx.generics_of(parent_sig_id); + own_params.append(&mut parent_sig_generics.own_params.clone()); + } + own_params.append(&mut callee_generics.own_params.clone()); + + // Lifetimes go first. + own_params.sort_by_key(|key| key.kind.is_ty_or_const()); + + for (idx, param) in own_params.iter_mut().enumerate() { + param.index = idx as u32; + // Default parameters are not inherited: they are not allowed + // in fn's. + if let ty::GenericParamDefKind::Type { has_default, .. } + | ty::GenericParamDefKind::Const { has_default, .. } = &mut param.kind + { + *has_default = false; + } + } + + let param_def_id_to_index = + own_params.iter().map(|param| (param.def_id, param.index)).collect(); + + Some(ty::Generics { + parent: None, + parent_count: 0, + own_params, + param_def_id_to_index, + has_self: false, + has_late_bound_regions: callee_generics.has_late_bound_regions, + host_effect_index: callee_generics.host_effect_index, + }) +} + +pub(crate) fn inherit_predicates_for_delegation_item<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + sig_id: DefId, +) -> Option<ty::GenericPredicates<'tcx>> { + // FIXME(fn_delegation): Support generics on associated delegation items. + // Error will be reported in `check_constraints`. + if fn_kind(tcx, def_id.into()) != FnKind::Free { + return None; + } + + let callee_predicates = tcx.predicates_of(sig_id); + let args = create_generic_args(tcx, def_id, sig_id); + + let mut preds = vec![]; + if let Some(parent_id) = callee_predicates.parent { + preds.extend(tcx.predicates_of(parent_id).instantiate_own(tcx, args)); + } + preds.extend(callee_predicates.instantiate_own(tcx, args)); + + Some(ty::GenericPredicates { + parent: None, + predicates: tcx.arena.alloc_from_iter(preds), + effects_min_tys: ty::List::empty(), + }) +} + +fn check_constraints<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + sig_id: DefId, +) -> Result<(), ErrorGuaranteed> { + let mut ret = Ok(()); + + let mut emit = |descr| { + ret = Err(tcx.dcx().emit_err(crate::errors::UnsupportedDelegation { + span: tcx.def_span(def_id), + descr, + callee_span: tcx.def_span(sig_id), + })); + }; + + if tcx.has_host_param(sig_id) { + emit("delegation to a function with effect parameter is not supported yet"); + } + + if let Some(local_sig_id) = sig_id.as_local() + && tcx.hir().opt_delegation_sig_id(local_sig_id).is_some() + { + emit("recursive delegation is not supported yet"); + } + + if fn_kind(tcx, def_id.into()) != FnKind::Free { + let sig_generics = tcx.generics_of(sig_id); + let parent = tcx.parent(def_id.into()); + let parent_generics = tcx.generics_of(parent); + + let parent_has_self = parent_generics.has_self as usize; + let sig_has_self = sig_generics.has_self as usize; + + if sig_generics.count() > sig_has_self || parent_generics.count() > parent_has_self { + emit("early bound generics are not supported for associated delegation items"); + } + } + + ret +} + +pub(crate) fn inherit_sig_for_delegation_item<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, +) -> &'tcx [Ty<'tcx>] { + let sig_id = tcx.hir().opt_delegation_sig_id(def_id).unwrap(); + let caller_sig = tcx.fn_sig(sig_id); + if let Err(err) = check_constraints(tcx, def_id, sig_id) { + let sig_len = caller_sig.instantiate_identity().skip_binder().inputs().len() + 1; + let err_type = Ty::new_error(tcx, err); + return tcx.arena.alloc_from_iter((0..sig_len).map(|_| err_type)); + } + let args = create_generic_args(tcx, def_id, sig_id); + + // Bound vars are also inherited from `sig_id`. + // They will be rebound later in `lower_fn_ty`. + let sig = caller_sig.instantiate(tcx, args).skip_binder(); + let sig_iter = sig.inputs().iter().cloned().chain(std::iter::once(sig.output())); + tcx.arena.alloc_from_iter(sig_iter) +} diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index c364a561631..7034735aec0 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1,12 +1,15 @@ //! Errors emitted by `rustc_hir_analysis`. -use crate::fluent_generated as fluent; +use rustc_errors::codes::*; use rustc_errors::{ - codes::*, Applicability, Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, MultiSpan, + Applicability, Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, MultiSpan, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::Ty; -use rustc_span::{symbol::Ident, Span, Symbol}; +use rustc_span::symbol::Ident; +use rustc_span::{Span, Symbol}; + +use crate::fluent_generated as fluent; mod pattern_types; pub use pattern_types::*; pub mod wrong_number_of_generic_args; @@ -1572,7 +1575,7 @@ pub struct RefOfMutStatic<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_not_supported_delegation)] -pub struct NotSupportedDelegation<'a> { +pub struct UnsupportedDelegation<'a> { #[primary_span] pub span: Span, pub descr: &'a str, diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs index db91a6ab2f4..8ecf53bfacb 100644 --- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs @@ -1,11 +1,10 @@ -use rustc_errors::{ - codes::*, pluralize, Applicability, Diag, Diagnostic, EmissionGuarantee, MultiSpan, -}; +use std::iter; + +use rustc_errors::codes::*; +use rustc_errors::{pluralize, Applicability, Diag, Diagnostic, EmissionGuarantee, MultiSpan}; use rustc_hir as hir; use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt}; use rustc_span::def_id::DefId; -use std::iter; - use GenericArgsInfo::*; /// Handles the `wrong number of type / lifetime / ... arguments` family of error messages. diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 30c04aa47a3..7f4c75d3a6a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -1,7 +1,8 @@ use std::ops::ControlFlow; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; -use rustc_errors::{codes::*, struct_span_code_err}; +use rustc_errors::codes::*; +use rustc_errors::struct_span_code_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -15,8 +16,9 @@ use smallvec::SmallVec; use crate::bounds::Bounds; use crate::errors; -use crate::hir_ty_lowering::HirTyLowerer; -use crate::hir_ty_lowering::{AssocItemQSelf, OnlySelfBounds, PredicateFilter, RegionInferReason}; +use crate::hir_ty_lowering::{ + AssocItemQSelf, HirTyLowerer, OnlySelfBounds, PredicateFilter, RegionInferReason, +}; impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// Add a `Sized` bound to the `bounds` if appropriate. diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 20f06d77489..d77cbe30536 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -1,15 +1,9 @@ -use crate::errors::{ - self, AssocItemConstraintsNotAllowedHere, ManualImplementation, MissingTypeParams, - ParenthesizedFnTraitExpansion, TraitObjectDeclaredWithNoTraits, -}; -use crate::fluent_generated as fluent; -use crate::hir_ty_lowering::{AssocItemQSelf, HirTyLowerer}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::unord::UnordMap; -use rustc_errors::MultiSpan; +use rustc_errors::codes::*; use rustc_errors::{ - codes::*, pluralize, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, + pluralize, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, MultiSpan, }; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -17,21 +11,26 @@ use rustc_hir::def_id::DefId; use rustc_middle::bug; use rustc_middle::query::Key; use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _}; -use rustc_middle::ty::GenericParamDefKind; -use rustc_middle::ty::{self, suggest_constraining_type_param}; -use rustc_middle::ty::{AdtDef, Ty, TyCtxt, TypeVisitableExt}; -use rustc_middle::ty::{Binder, TraitRef}; +use rustc_middle::ty::{ + self, suggest_constraining_type_param, AdtDef, Binder, GenericParamDefKind, TraitRef, Ty, + TyCtxt, TypeVisitableExt, +}; use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::symbol::{kw, sym, Ident}; -use rustc_span::BytePos; -use rustc_span::{Span, Symbol, DUMMY_SP}; +use rustc_span::{BytePos, Span, Symbol, DUMMY_SP}; use rustc_trait_selection::error_reporting::traits::report_object_safety_error; -use rustc_trait_selection::traits::FulfillmentError; use rustc_trait_selection::traits::{ - object_safety_violations_for_assoc_item, TraitAliasExpansionInfo, + object_safety_violations_for_assoc_item, FulfillmentError, TraitAliasExpansionInfo, }; +use crate::errors::{ + self, AssocItemConstraintsNotAllowedHere, ManualImplementation, MissingTypeParams, + ParenthesizedFnTraitExpansion, TraitObjectDeclaredWithNoTraits, +}; +use crate::fluent_generated as fluent; +use crate::hir_ty_lowering::{AssocItemQSelf, HirTyLowerer}; + impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// On missing type parameters, emit an E0393 error and provide a structured suggestion using /// the type parameter's name as a placeholder. diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index abe2cff321f..a59e9aa85fd 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -1,13 +1,6 @@ -use super::{HirTyLowerer, IsMethodCall}; -use crate::errors::wrong_number_of_generic_args::{GenericArgsInfo, WrongNumberOfGenericArgs}; -use crate::hir_ty_lowering::{ - errors::prohibit_assoc_item_constraint, ExplicitLateBound, GenericArgCountMismatch, - GenericArgCountResult, GenericArgPosition, GenericArgsLowerer, -}; use rustc_ast::ast::ParamKindOrd; -use rustc_errors::{ - codes::*, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, MultiSpan, -}; +use rustc_errors::codes::*; +use rustc_errors::{struct_span_code_err, Applicability, Diag, ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; @@ -19,6 +12,14 @@ use rustc_session::lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS; use rustc_span::symbol::{kw, sym}; use smallvec::SmallVec; +use super::{HirTyLowerer, IsMethodCall}; +use crate::errors::wrong_number_of_generic_args::{GenericArgsInfo, WrongNumberOfGenericArgs}; +use crate::hir_ty_lowering::errors::prohibit_assoc_item_constraint; +use crate::hir_ty_lowering::{ + ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgPosition, + GenericArgsLowerer, +}; + /// Report an error that a generic argument did not match the generic parameter that was /// expected. fn generic_arg_mismatch_err( @@ -252,32 +253,6 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( match (args_iter.peek(), params.peek()) { (Some(&arg), Some(¶m)) => { match (arg, ¶m.kind, arg_count.explicit_late_bound) { - ( - GenericArg::Const(hir::ConstArg { - is_desugared_from_effects: true, - .. - }), - GenericParamDefKind::Const { is_host_effect: false, .. } - | GenericParamDefKind::Type { .. } - | GenericParamDefKind::Lifetime, - _, - ) => { - // FIXME(effects): this should be removed - // SPECIAL CASE FOR DESUGARED EFFECT PARAMS - // This comes from the following example: - // - // ``` - // #[const_trait] - // pub trait PartialEq<Rhs: ?Sized = Self> {} - // impl const PartialEq for () {} - // ``` - // - // Since this is a const impl, we need to insert a host arg at the end of - // `PartialEq`'s generics, but this errors since `Rhs` isn't specified. - // To work around this, we infer all arguments until we reach the host param. - args.push(ctx.inferred_kind(&args, param, infer_args)); - params.next(); - } (GenericArg::Lifetime(_), GenericParamDefKind::Lifetime, _) | ( GenericArg::Type(_) | GenericArg::Infer(_), @@ -551,21 +526,34 @@ pub(crate) fn check_generic_arg_count( synth_provided, } } else { - let num_missing_args = expected_max - provided; + // Check if associated type bounds are incorrectly written in impl block header like: + // ``` + // trait Foo<T> {} + // impl Foo<T: Default> for u8 {} + // ``` + let parent_is_impl_block = cx + .tcx() + .hir() + .parent_owner_iter(seg.hir_id) + .next() + .is_some_and(|(_, owner_node)| owner_node.is_impl_block()); + if parent_is_impl_block { + let constraint_names: Vec<_> = + gen_args.constraints.iter().map(|b| b.ident.name).collect(); + let param_names: Vec<_> = gen_params + .own_params + .iter() + .filter(|param| !has_self || param.index != 0) // Assumes `Self` will always be the first parameter + .map(|param| param.name) + .collect(); + if constraint_names == param_names { + // We set this to true and delay emitting `WrongNumberOfGenericArgs` + // to provide a succinct error for cases like issue #113073 + all_params_are_binded = true; + }; + } - let constraint_names: Vec<_> = - gen_args.constraints.iter().map(|b| b.ident.name).collect(); - let param_names: Vec<_> = gen_params - .own_params - .iter() - .filter(|param| !has_self || param.index != 0) // Assumes `Self` will always be the first parameter - .map(|param| param.name) - .collect(); - if constraint_names == param_names { - // We set this to true and delay emitting `WrongNumberOfGenericArgs` - // to provide a succinct error for cases like issue #113073 - all_params_are_binded = true; - }; + let num_missing_args = expected_max - provided; GenericArgsInfo::MissingTypesOrConsts { num_missing_args, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index e7aad0a29c5..6aff518390f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -1,8 +1,10 @@ use rustc_ast::TraitObjectSyntax; -use rustc_errors::{codes::*, Diag, EmissionGuarantee, StashKey}; +use rustc_errors::codes::*; +use rustc_errors::{Diag, EmissionGuarantee, StashKey}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_lint_defs::{builtin::BARE_TRAIT_OBJECTS, Applicability}; +use rustc_lint_defs::builtin::BARE_TRAIT_OBJECTS; +use rustc_lint_defs::Applicability; use rustc_span::Span; use rustc_trait_selection::error_reporting::traits::suggestions::NextTypeParamName; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index ce298641e60..d865357b829 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -20,17 +20,13 @@ pub mod generics; mod lint; mod object_safety; -use crate::bounds::Bounds; -use crate::errors::{AmbiguousLifetimeBound, WildPatTy}; -use crate::hir_ty_lowering::errors::{prohibit_assoc_item_constraint, GenericsArgsErrExtend}; -use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args}; -use crate::middle::resolve_bound_vars as rbv; -use crate::require_c_abi_if_c_variadic; +use std::slice; + use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; +use rustc_errors::codes::*; use rustc_errors::{ - codes::*, struct_span_code_err, Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, - FatalError, + struct_span_code_err, Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, }; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; @@ -55,7 +51,12 @@ use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::wf::object_region_bounds; use rustc_trait_selection::traits::{self, ObligationCtxt}; -use std::slice; +use crate::bounds::Bounds; +use crate::errors::{AmbiguousLifetimeBound, WildPatTy}; +use crate::hir_ty_lowering::errors::{prohibit_assoc_item_constraint, GenericsArgsErrExtend}; +use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args}; +use crate::middle::resolve_bound_vars as rbv; +use crate::require_c_abi_if_c_variadic; /// A path segment that is semantically allowed to have generic arguments. #[derive(Debug)] @@ -2006,93 +2007,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.lower_ty_common(hir_ty, false, true) } - fn check_delegation_constraints(&self, sig_id: DefId, span: Span, emit: bool) -> bool { - let mut error_occured = false; - let sig_span = self.tcx().def_span(sig_id); - let mut try_emit = |descr| { - if emit { - self.dcx().emit_err(crate::errors::NotSupportedDelegation { - span, - descr, - callee_span: sig_span, - }); - } - error_occured = true; - }; - - if let Some(node) = self.tcx().hir().get_if_local(sig_id) - && let Some(decl) = node.fn_decl() - && let hir::FnRetTy::Return(ty) = decl.output - && let hir::TyKind::InferDelegation(_, _) = ty.kind - { - try_emit("recursive delegation"); - } - - let sig_generics = self.tcx().generics_of(sig_id); - let parent = self.tcx().local_parent(self.item_def_id()); - let parent_generics = self.tcx().generics_of(parent); - - let parent_is_trait = (self.tcx().def_kind(parent) == DefKind::Trait) as usize; - let sig_has_self = sig_generics.has_self as usize; - - if sig_generics.count() > sig_has_self || parent_generics.count() > parent_is_trait { - try_emit("delegation with early bound generics"); - } - - // There is no way to instantiate `Self` param for caller if - // 1. callee is a trait method - // 2. delegation item isn't an associative item - if let DefKind::AssocFn = self.tcx().def_kind(sig_id) - && let DefKind::Fn = self.tcx().def_kind(self.item_def_id()) - && self.tcx().associated_item(sig_id).container - == ty::AssocItemContainer::TraitContainer - { - try_emit("delegation to a trait method from a free function"); - } - - error_occured - } - - fn lower_delegation_ty( - &self, - sig_id: DefId, - idx: hir::InferDelegationKind, - span: Span, - ) -> Ty<'tcx> { - if self.check_delegation_constraints(sig_id, span, idx == hir::InferDelegationKind::Output) - { - let e = self.dcx().span_delayed_bug(span, "not supported delegation case"); - return Ty::new_error(self.tcx(), e); - }; - let sig = self.tcx().fn_sig(sig_id); - let sig_generics = self.tcx().generics_of(sig_id); - - let parent = self.tcx().local_parent(self.item_def_id()); - let parent_def_kind = self.tcx().def_kind(parent); - - let sig = if let DefKind::Impl { .. } = parent_def_kind - && sig_generics.has_self - { - // Generic params can't be here except the trait self type. - // They are not supported yet. - assert_eq!(sig_generics.count(), 1); - assert_eq!(self.tcx().generics_of(parent).count(), 0); - - let self_ty = self.tcx().type_of(parent).instantiate_identity(); - let generic_self_ty = ty::GenericArg::from(self_ty); - let args = self.tcx().mk_args_from_iter(std::iter::once(generic_self_ty)); - sig.instantiate(self.tcx(), args) - } else { - sig.instantiate_identity() - }; - - // Bound vars are also inherited from `sig_id`. - // They will be rebound later in `lower_fn_ty`. - let sig = sig.skip_binder(); - + fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> { + let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id()); match idx { - hir::InferDelegationKind::Input(id) => sig.inputs()[id], - hir::InferDelegationKind::Output => sig.output(), + hir::InferDelegationKind::Input(idx) => delegation_sig[idx], + hir::InferDelegationKind::Output => *delegation_sig.last().unwrap(), } } @@ -2109,9 +2028,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let tcx = self.tcx(); let result_ty = match &hir_ty.kind { - hir::TyKind::InferDelegation(sig_id, idx) => { - self.lower_delegation_ty(*sig_id, *idx, hir_ty.span) - } + hir::TyKind::InferDelegation(_, idx) => self.lower_delegation_ty(*idx), hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.lower_ty(ty)), hir::TyKind::Ptr(mt) => Ty::new_ptr(tcx, self.lower_ty(mt.ty), mt.mutbl), hir::TyKind::Ref(region, mt) => { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs index b3c7a1ff8a8..31d1750f33d 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs @@ -1,24 +1,25 @@ -use crate::bounds::Bounds; -use crate::hir_ty_lowering::{ - GenericArgCountMismatch, GenericArgCountResult, OnlySelfBounds, RegionInferReason, -}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; -use rustc_errors::{codes::*, struct_span_code_err}; +use rustc_errors::codes::*; +use rustc_errors::struct_span_code_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS; use rustc_middle::span_bug; use rustc_middle::ty::fold::BottomUpFolder; -use rustc_middle::ty::{self, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable}; -use rustc_middle::ty::{DynKind, Upcast}; +use rustc_middle::ty::{ + self, DynKind, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable, Upcast, +}; use rustc_span::{ErrorGuaranteed, Span}; use rustc_trait_selection::error_reporting::traits::report_object_safety_error; use rustc_trait_selection::traits::{self, hir_ty_lowering_object_safety_violations}; - use smallvec::{smallvec, SmallVec}; use super::HirTyLowerer; +use crate::bounds::Bounds; +use crate::hir_ty_lowering::{ + GenericArgCountMismatch, GenericArgCountResult, OnlySelfBounds, RegionInferReason, +}; impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// Lower a trait object type from the HIR to our internal notion of a type. diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index 13993a1992b..7d2cabd3f2c 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -1,4 +1,3 @@ -use crate::collect::ItemCtxt; use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{ForeignItem, ForeignItemKind}; @@ -10,6 +9,8 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_span::def_id::LocalDefId; use rustc_trait_selection::traits::{self, ObligationCtxt}; +use crate::collect::ItemCtxt; + pub fn provide(providers: &mut Providers) { *providers = Providers { diagnostic_hir_wf_check, ..*providers }; } diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index f0fcbd5528f..ab441ed4cde 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -8,9 +8,9 @@ //! specialization errors. These things can (and probably should) be //! fixed, but for the moment it's easier to do these checks early. -use crate::{constrained_generic_params as cgp, errors::UnconstrainedGenericParameter}; -use min_specialization::check_min_specialization; +use std::assert_matches::debug_assert_matches; +use min_specialization::check_min_specialization; use rustc_data_structures::fx::FxHashSet; use rustc_errors::codes::*; use rustc_hir::def::DefKind; @@ -18,6 +18,9 @@ use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_span::ErrorGuaranteed; +use crate::constrained_generic_params as cgp; +use crate::errors::UnconstrainedGenericParameter; + mod min_specialization; /// Checks that all the type/lifetime parameters on an impl also @@ -53,7 +56,7 @@ mod min_specialization; pub fn check_impl_wf(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { let min_specialization = tcx.features().min_specialization; let mut res = Ok(()); - debug_assert!(matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. })); + debug_assert_matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. }); res = res.and(enforce_impl_params_are_constrained(tcx, impl_def_id)); if min_specialization { res = res.and(check_min_specialization(tcx, impl_def_id)); diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 2e5f99bb78b..f44a78bac4d 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -65,9 +65,6 @@ //! cause use after frees with purely safe code in the same way as specializing //! on traits with methods can. -use crate::errors::GenericArgsOnOverriddenImpl; -use crate::{constrained_generic_params as cgp, errors}; - use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -75,13 +72,15 @@ use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::specialization_graph::Node; use rustc_middle::ty::trait_def::TraitSpecializationKind; -use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; -use rustc_middle::ty::{GenericArg, GenericArgs, GenericArgsRef}; +use rustc_middle::ty::{self, GenericArg, GenericArgs, GenericArgsRef, TyCtxt, TypeVisitableExt}; use rustc_span::{ErrorGuaranteed, Span}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::{self, translate_args_with_cause, wf, ObligationCtxt}; +use crate::errors::GenericArgsOnOverriddenImpl; +use crate::{constrained_generic_params as cgp, errors}; + pub(super) fn check_min_specialization( tcx: TyCtxt<'_>, impl_def_id: LocalDefId, diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 89b981ab80d..291d57f2a17 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -62,6 +62,7 @@ This API is completely unstable and subject to change. #![allow(rustc::untranslatable_diagnostic)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] +#![feature(assert_matches)] #![feature(control_flow_enum)] #![feature(if_let_guard)] #![feature(iter_intersperse)] @@ -83,6 +84,7 @@ pub mod autoderef; mod bounds; mod check_unused; mod coherence; +mod delegation; pub mod hir_ty_lowering; // FIXME: This module shouldn't be public. pub mod collect; @@ -100,7 +102,8 @@ use rustc_middle::mir::interpret::GlobalId; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::parse::feature_err; -use rustc_span::{symbol::sym, Span}; +use rustc_span::symbol::sym; +use rustc_span::Span; use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits; @@ -145,6 +148,10 @@ pub fn provide(providers: &mut Providers) { variance::provide(providers); outlives::provide(providers); hir_wf_check::provide(providers); + *providers = Providers { + inherit_sig_for_delegation_item: delegation::inherit_sig_for_delegation_item, + ..*providers + }; } pub fn check_crate(tcx: TyCtxt<'_>) { diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs index d953736c28c..454c20d3e64 100644 --- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs +++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs @@ -1,8 +1,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; -use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::ty::{GenericArg, GenericArgKind}; +use rustc_middle::ty::{self, GenericArg, GenericArgKind, Ty, TyCtxt}; use rustc_span::Span; use super::explicit::ExplicitPredicatesMap; diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs index 1f74ebf99f1..cb61ef7c64d 100644 --- a/compiler/rustc_hir_analysis/src/outlives/mod.rs +++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs @@ -1,8 +1,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::query::Providers; -use rustc_middle::ty::GenericArgKind; -use rustc_middle::ty::{self, CratePredicatesMap, TyCtxt, Upcast}; +use rustc_middle::ty::{self, CratePredicatesMap, GenericArgKind, TyCtxt, Upcast}; use rustc_span::Span; pub(crate) mod dump; diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs index 08015c28a26..a1eccc91dea 100644 --- a/compiler/rustc_hir_analysis/src/outlives/utils.rs +++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs @@ -1,6 +1,5 @@ use rustc_data_structures::fx::FxIndexMap; -use rustc_middle::ty::{self, Region, Ty, TyCtxt}; -use rustc_middle::ty::{GenericArg, GenericArgKind}; +use rustc_middle::ty::{self, GenericArg, GenericArgKind, Region, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_span::Span; use rustc_type_ir::outlives::{push_outlives_components, Component}; diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index 0c436e21c16..92baa41e07f 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -6,8 +6,7 @@ use hir::def_id::{DefId, LocalDefId}; use rustc_hir as hir; use rustc_hir::def::DefKind; -use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::ty::{GenericArgKind, GenericArgsRef}; +use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use super::terms::VarianceTerm::*; diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 29f96e27b64..8a4114c3e4b 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -9,8 +9,9 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::query::Providers; use rustc_middle::span_bug; -use rustc_middle::ty::{self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt}; -use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable}; +use rustc_middle::ty::{ + self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, +}; /// Defines the `TermsContext` basically houses an arena where we can /// allocate terms. diff --git a/compiler/rustc_hir_analysis/src/variance/terms.rs b/compiler/rustc_hir_analysis/src/variance/terms.rs index 275df24956c..36bff60e019 100644 --- a/compiler/rustc_hir_analysis/src/variance/terms.rs +++ b/compiler/rustc_hir_analysis/src/variance/terms.rs @@ -9,11 +9,12 @@ // `InferredIndex` is a newtype'd int representing the index of such // a variable. +use std::fmt; + use rustc_arena::DroplessArena; use rustc_hir::def::DefKind; use rustc_hir::def_id::{LocalDefId, LocalDefIdMap}; use rustc_middle::ty::{self, TyCtxt}; -use std::fmt; use self::VarianceTerm::*; |
