diff options
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/autoderef.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/check.rs | 56 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/intrinsic.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/mod.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/region.rs | 21 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/collect.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/errors.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/lib.rs | 19 |
10 files changed, 106 insertions, 54 deletions
diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index 99e495d9266..c88c534e135 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -160,7 +160,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { self.param_env, ty::Binder::dummy(trait_ref), ); - if !self.infcx.predicate_may_hold(&obligation) { + if !self.infcx.next_trait_solver() && !self.infcx.predicate_may_hold(&obligation) { debug!("overloaded_deref_ty: cannot match obligation"); return None; } @@ -184,17 +184,17 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { self.param_env, ty, ) else { - // We shouldn't have errors here, except for evaluate/fulfill mismatches, - // but that's not a reason for an ICE (`predicate_may_hold` is conservative - // by design). - // FIXME(-Znext-solver): This *actually* shouldn't happen then. + // We shouldn't have errors here in the old solver, except for + // evaluate/fulfill mismatches, but that's not a reason for an ICE. return None; }; let errors = ocx.select_where_possible(); if !errors.is_empty() { - // This shouldn't happen, except for evaluate/fulfill mismatches, - // but that's not a reason for an ICE (`predicate_may_hold` is conservative - // by design). + if self.infcx.next_trait_solver() { + unreachable!(); + } + // We shouldn't have errors here in the old solver, except for + // evaluate/fulfill mismatches, but that's not a reason for an ICE. debug!(?errors, "encountered errors while fulfilling"); return None; } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 064b42413f0..32fec0604c0 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -21,7 +21,7 @@ use rustc_middle::ty::error::TypeErrorToStringExt; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::util::Discr; use rustc_middle::ty::{ - AdtDef, BottomUpFolder, GenericArgKind, RegionKind, TypeFoldable, TypeSuperVisitable, + AdtDef, BottomUpFolder, FnSig, GenericArgKind, RegionKind, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, fold_regions, }; use rustc_session::lint::builtin::UNINHABITED_STATIC; @@ -37,22 +37,23 @@ use {rustc_attr_data_structures as attrs, rustc_hir as hir}; use super::compare_impl_item::check_type_bounds; use super::*; +fn add_abi_diag_help<T: EmissionGuarantee>(abi: ExternAbi, diag: &mut Diag<'_, T>) { + if let ExternAbi::Cdecl { unwind } = abi { + let c_abi = ExternAbi::C { unwind }; + diag.help(format!("use `extern {c_abi}` instead",)); + } else if let ExternAbi::Stdcall { unwind } = abi { + let c_abi = ExternAbi::C { unwind }; + let system_abi = ExternAbi::System { unwind }; + diag.help(format!( + "if you need `extern {abi}` on win32 and `extern {c_abi}` everywhere else, \ + use `extern {system_abi}`" + )); + } +} + pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi) { // FIXME: this should be checked earlier, e.g. in `rustc_ast_lowering`, to fix // things like #86232. - fn add_help<T: EmissionGuarantee>(abi: ExternAbi, diag: &mut Diag<'_, T>) { - if let ExternAbi::Cdecl { unwind } = abi { - let c_abi = ExternAbi::C { unwind }; - diag.help(format!("use `extern {c_abi}` instead",)); - } else if let ExternAbi::Stdcall { unwind } = abi { - let c_abi = ExternAbi::C { unwind }; - let system_abi = ExternAbi::System { unwind }; - diag.help(format!( - "if you need `extern {abi}` on win32 and `extern {c_abi}` everywhere else, \ - use `extern {system_abi}`" - )); - } - } match AbiMap::from_target(&tcx.sess.target).canonize_abi(abi, false) { AbiMapping::Direct(..) => (), @@ -63,13 +64,13 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi E0570, "`{abi}` is not a supported ABI for the current target", ); - add_help(abi, &mut err); + add_abi_diag_help(abi, &mut err); err.emit(); } AbiMapping::Deprecated(..) => { tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| { lint.primary_message("use of calling convention not supported on this target"); - add_help(abi, lint); + add_abi_diag_help(abi, lint); }); } } @@ -80,7 +81,16 @@ pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ex // in `check_abi` above. match AbiMap::from_target(&tcx.sess.target).canonize_abi(abi, false) { AbiMapping::Direct(..) => (), - AbiMapping::Deprecated(..) | AbiMapping::Invalid => { + // This is not a redundant match arm: these ABIs started linting after introducing + // UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS already existed and we want to + // avoid expanding the scope of that lint so it can move to a hard error sooner. + AbiMapping::Deprecated(..) => { + tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| { + lint.primary_message("use of calling convention not supported on this target"); + add_abi_diag_help(abi, lint); + }); + } + AbiMapping::Invalid => { tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| { lint.primary_message(format!( "the calling convention {abi} is not supported on this target" @@ -90,6 +100,18 @@ pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ex } } +pub fn check_custom_abi(tcx: TyCtxt<'_>, def_id: LocalDefId, fn_sig: FnSig<'_>, fn_sig_span: Span) { + if fn_sig.abi == ExternAbi::Custom { + // Function definitions that use `extern "custom"` must be naked functions. + if !tcx.has_attr(def_id, sym::naked) { + tcx.dcx().emit_err(crate::errors::AbiCustomClothedFunction { + span: fn_sig_span, + naked_span: tcx.def_span(def_id).shrink_to_lo(), + }); + } + } +} + fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) { let def = tcx.adt_def(def_id); let span = tcx.def_span(def_id); diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 481cdaa4c6c..060fc51b7bd 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -71,7 +71,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::box_new | sym::breakpoint | sym::size_of - | sym::min_align_of + | sym::align_of | sym::needs_drop | sym::caller_location | sym::add_with_overflow @@ -200,10 +200,8 @@ pub(crate) fn check_intrinsic_type( sym::abort => (0, 0, vec![], tcx.types.never), sym::unreachable => (0, 0, vec![], tcx.types.never), sym::breakpoint => (0, 0, vec![], tcx.types.unit), - sym::size_of | sym::pref_align_of | sym::min_align_of | sym::variant_count => { - (1, 0, vec![], tcx.types.usize) - } - sym::size_of_val | sym::min_align_of_val => { + sym::size_of | sym::align_of | sym::variant_count => (1, 0, vec![], tcx.types.usize), + sym::size_of_val | sym::align_of_val => { (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize) } sym::rustc_peek => (1, 0, vec![param(0)], param(0)), diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index fad8abf5fae..c5c7e6b2aa7 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -72,7 +72,7 @@ pub mod wfcheck; use std::num::NonZero; -pub use check::{check_abi, check_abi_fn_ptr}; +pub use check::{check_abi, check_abi_fn_ptr, check_custom_abi}; use rustc_abi::{ExternAbi, VariantIdx}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::{Diag, ErrorGuaranteed, pluralize, struct_span_code_err}; diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 7cb31a64e13..c458878da15 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -10,6 +10,7 @@ use std::mem; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; +use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Arm, Block, Expr, LetStmt, Pat, PatKind, Stmt}; @@ -752,13 +753,19 @@ fn resolve_local<'tcx>( record_rvalue_scope_if_borrow_expr(visitor, arm.body, blk_id); } } - hir::ExprKind::Call(..) | hir::ExprKind::MethodCall(..) => { - // FIXME(@dingxiangfei2009): choose call arguments here - // for candidacy for extended parameter rule application - } - hir::ExprKind::Index(..) => { - // FIXME(@dingxiangfei2009): select the indices - // as candidate for rvalue scope rules + hir::ExprKind::Call(func, args) => { + // Recurse into tuple constructors, such as `Some(&temp())`. + // + // That way, there is no difference between `Some(..)` and `Some { 0: .. }`, + // even though the former is syntactically a function call. + if let hir::ExprKind::Path(path) = &func.kind + && let hir::QPath::Resolved(None, path) = path + && let Res::SelfCtor(_) | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) = path.res + { + for arg in args { + record_rvalue_scope_if_borrow_expr(visitor, arg, blk_id); + } + } } _ => {} } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index e1df0d60452..6e22ac5a28a 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -494,7 +494,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { // Only visit the type looking for `_` if we didn't fix the type above visitor.visit_ty_unambig(a); - self.lowerer().lower_arg_ty(a, None) + self.lowerer().lower_ty(a) }) .collect(); diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index a27d1ed6c53..809cb311c1f 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1698,3 +1698,17 @@ pub(crate) struct SelfInTypeAlias { #[label] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_abi_custom_clothed_function)] +pub(crate) struct AbiCustomClothedFunction { + #[primary_span] + pub span: Span, + #[suggestion( + hir_analysis_suggestion, + applicability = "maybe-incorrect", + code = "#[unsafe(naked)]\n", + style = "short" + )] + pub naked_span: Span, +} 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 bdc42c7a2d9..106420faa4c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -9,8 +9,8 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::bug; use rustc_middle::ty::{ - self as ty, IsSuggestable, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, - TypeVisitableExt, TypeVisitor, Upcast, + self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, + TypeVisitor, Upcast, }; use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym}; use rustc_trait_selection::traits; @@ -927,7 +927,7 @@ struct GenericParamAndBoundVarCollector<'a, 'tcx> { impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'_, 'tcx> { type Result = ControlFlow<ErrorGuaranteed>; - fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>( + fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( &mut self, binder: &ty::Binder<'tcx, T>, ) -> Self::Result { 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 4c65d0d0510..bf407cbaccb 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -805,7 +805,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity }) }); let bound = (bound.upcast(tcx), span); - // FIXME(-Znext-solver): We can likely remove this hack once the new trait solver lands. + // FIXME(-Znext-solver): We can likely remove this hack once the + // new trait solver lands. This fixed an overflow in the old solver. + // This may have performance implications, so please check perf when + // removing it. + // This was added in <https://github.com/rust-lang/rust/pull/123302>. if tcx.is_lang_item(trait_def_id, rustc_hir::LangItem::Sized) { bounds.insert(0, bound); } else { @@ -2704,16 +2708,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } - pub fn lower_arg_ty(&self, ty: &hir::Ty<'tcx>, expected_ty: Option<Ty<'tcx>>) -> Ty<'tcx> { - match ty.kind { - hir::TyKind::Infer(()) if let Some(expected_ty) = expected_ty => { - self.record_ty(ty.hir_id, expected_ty, ty.span); - expected_ty - } - _ => self.lower_ty(ty), - } - } - /// Lower a function type from the HIR to our internal notion of a function signature. #[instrument(level = "debug", skip(self, hir_id, safety, abi, decl, generics, hir_ty), ret)] pub fn lower_fn_ty( diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index a92ee89186c..007f3a6abf6 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -92,8 +92,9 @@ mod variance; pub use errors::NoVariantNamed; use rustc_abi::ExternAbi; -use rustc_hir as hir; use rustc_hir::def::DefKind; +use rustc_hir::lints::DelayedLint; +use rustc_hir::{self as hir}; use rustc_middle::middle; use rustc_middle::mir::interpret::GlobalId; use rustc_middle::query::Providers; @@ -174,6 +175,14 @@ pub fn provide(providers: &mut Providers) { }; } +fn emit_delayed_lint(lint: &DelayedLint, tcx: TyCtxt<'_>) { + match lint { + DelayedLint::AttributeParsing(attribute_lint) => { + rustc_attr_parsing::emit_attribute_lint(attribute_lint, tcx) + } + } +} + pub fn check_crate(tcx: TyCtxt<'_>) { let _prof_timer = tcx.sess.timer("type_check_crate"); @@ -192,6 +201,14 @@ pub fn check_crate(tcx: TyCtxt<'_>) { let _: R = tcx.ensure_ok().crate_inherent_impls_overlap_check(()); }); + for owner_id in tcx.hir_crate_items(()).owners() { + if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) { + for lint in &delayed_lints.lints { + emit_delayed_lint(lint, tcx); + } + } + } + tcx.par_hir_body_owners(|item_def_id| { let def_kind = tcx.def_kind(item_def_id); // Make sure we evaluate all static and (non-associated) const items, even if unused. |
