diff options
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/astconv/errors.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/astconv/object_safety.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/check.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/compare_impl_item.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/entry.rs | 277 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/mod.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/wfcheck.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/lib.rs | 270 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/variance/mod.rs | 2 |
9 files changed, 295 insertions, 280 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs index 8aaa005a24d..7f4927bbb98 100644 --- a/compiler/rustc_hir_analysis/src/astconv/errors.rs +++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs @@ -123,7 +123,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let all_candidate_names: Vec<_> = all_candidates() .flat_map(|r| self.tcx().associated_items(r.def_id()).in_definition_order()) .filter_map(|item| { - if item.opt_rpitit_info.is_none() && item.kind == ty::AssocKind::Type { + if !item.is_impl_trait_in_trait() && item.kind == ty::AssocKind::Type { Some(item.name) } else { None @@ -164,7 +164,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.tcx().associated_items(*trait_def_id).in_definition_order() }) .filter_map(|item| { - if item.opt_rpitit_info.is_none() && item.kind == ty::AssocKind::Type { + if !item.is_impl_trait_in_trait() && item.kind == ty::AssocKind::Type { Some(item.name) } else { None diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs index 034f2e4da01..a36ec0c5730 100644 --- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs @@ -173,7 +173,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.associated_items(pred.def_id()) .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Type) - .filter(|item| item.opt_rpitit_info.is_none()) + .filter(|item| !item.is_impl_trait_in_trait()) .map(|item| item.def_id), ); } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index a4ef8e43527..d9e14096954 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -8,7 +8,7 @@ use rustc_attr as attr; use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; use rustc_hir::intravisit::Visitor; use rustc_hir::{ItemKind, Node, PathSegment}; use rustc_infer::infer::opaque_types::ConstrainOpaqueTypeRegionVisitor; @@ -1378,6 +1378,9 @@ pub(super) fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { for id in module.items() { check_item_type(tcx, id); } + if module_def_id == CRATE_DEF_ID { + super::entry::check_for_entry_fn(tcx); + } } fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) -> ErrorGuaranteed { 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 2075b1add39..89877280a73 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -867,7 +867,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> { }); self.types.insert(proj.def_id, (infer_ty, proj.args)); // Recurse into bounds - for (pred, pred_span) in self.interner().explicit_item_bounds(proj.def_id).arg_iter_copied(self.interner(), proj.args) { + for (pred, pred_span) in self.interner().explicit_item_bounds(proj.def_id).iter_instantiated_copied(self.interner(), proj.args) { let pred = pred.fold_with(self); let pred = self.ocx.normalize( &ObligationCause::misc(self.span, self.body_id), @@ -1322,7 +1322,7 @@ fn compare_number_of_generics<'tcx>( // has mismatched type or const generic arguments, then the method that it's // inheriting the generics from will also have mismatched arguments, and // we'll report an error for that instead. Delay a bug for safety, though. - if trait_.opt_rpitit_info.is_some() { + if trait_.is_impl_trait_in_trait() { return Err(tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, "errors comparing numbers of generics of trait/impl functions were not emitted", @@ -2116,7 +2116,7 @@ pub(super) fn check_type_bounds<'tcx>( // A synthetic impl Trait for RPITIT desugaring has no HIR, which we currently use to get the // span for an impl's associated type. Instead, for these, use the def_span for the synthesized // associated type. - let impl_ty_span = if impl_ty.opt_rpitit_info.is_some() { + let impl_ty_span = if impl_ty.is_impl_trait_in_trait() { tcx.def_span(impl_ty_def_id) } else { match tcx.hir().get_by_def_id(impl_ty_def_id) { @@ -2149,7 +2149,7 @@ pub(super) fn check_type_bounds<'tcx>( let obligations: Vec<_> = tcx .explicit_item_bounds(trait_ty.def_id) - .arg_iter_copied(tcx, rebased_args) + .iter_instantiated_copied(tcx, rebased_args) .map(|(concrete_ty_bound, span)| { debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound); traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound) diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs new file mode 100644 index 00000000000..fcaefe0261b --- /dev/null +++ b/compiler/rustc_hir_analysis/src/check/entry.rs @@ -0,0 +1,277 @@ +use rustc_hir as hir; +use rustc_hir::Node; +use rustc_infer::infer::TyCtxtInferExt; +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_target::spec::abi::Abi; +use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; +use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode}; + +use std::ops::Not; + +use crate::errors; +use crate::require_same_types; + +pub(crate) fn check_for_entry_fn(tcx: TyCtxt<'_>) { + match tcx.entry_fn(()) { + Some((def_id, EntryFnType::Main { .. })) => check_main_fn_ty(tcx, def_id), + Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id), + _ => {} + } +} + +fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { + let main_fnsig = tcx.fn_sig(main_def_id).instantiate_identity(); + let main_span = tcx.def_span(main_def_id); + + fn main_fn_diagnostics_def_id(tcx: TyCtxt<'_>, def_id: DefId, sp: Span) -> LocalDefId { + if let Some(local_def_id) = def_id.as_local() { + let hir_type = tcx.type_of(local_def_id).instantiate_identity(); + if !matches!(hir_type.kind(), ty::FnDef(..)) { + span_bug!(sp, "main has a non-function type: found `{}`", hir_type); + } + local_def_id + } else { + CRATE_DEF_ID + } + } + + fn main_fn_generics_params_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> { + if !def_id.is_local() { + return None; + } + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); + match tcx.hir().find(hir_id) { + Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => { + generics.params.is_empty().not().then_some(generics.span) + } + _ => { + span_bug!(tcx.def_span(def_id), "main has a non-function type"); + } + } + } + + fn main_fn_where_clauses_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> { + if !def_id.is_local() { + return None; + } + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); + match tcx.hir().find(hir_id) { + Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => { + Some(generics.where_clause_span) + } + _ => { + span_bug!(tcx.def_span(def_id), "main has a non-function type"); + } + } + } + + fn main_fn_asyncness_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> { + if !def_id.is_local() { + return None; + } + Some(tcx.def_span(def_id)) + } + + fn main_fn_return_type_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> { + if !def_id.is_local() { + return None; + } + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); + match tcx.hir().find(hir_id) { + Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. })) => { + Some(fn_sig.decl.output.span()) + } + _ => { + span_bug!(tcx.def_span(def_id), "main has a non-function type"); + } + } + } + + let mut error = false; + let main_diagnostics_def_id = main_fn_diagnostics_def_id(tcx, main_def_id, main_span); + let main_fn_generics = tcx.generics_of(main_def_id); + let main_fn_predicates = tcx.predicates_of(main_def_id); + if main_fn_generics.count() != 0 || !main_fnsig.bound_vars().is_empty() { + let generics_param_span = main_fn_generics_params_span(tcx, main_def_id); + tcx.sess.emit_err(errors::MainFunctionGenericParameters { + span: generics_param_span.unwrap_or(main_span), + label_span: generics_param_span, + }); + error = true; + } else if !main_fn_predicates.predicates.is_empty() { + // generics may bring in implicit predicates, so we skip this check if generics is present. + let generics_where_clauses_span = main_fn_where_clauses_span(tcx, main_def_id); + tcx.sess.emit_err(errors::WhereClauseOnMain { + span: generics_where_clauses_span.unwrap_or(main_span), + generics_span: generics_where_clauses_span, + }); + error = true; + } + + let main_asyncness = tcx.asyncness(main_def_id); + if let hir::IsAsync::Async = main_asyncness { + let asyncness_span = main_fn_asyncness_span(tcx, main_def_id); + tcx.sess.emit_err(errors::MainFunctionAsync { span: main_span, asyncness: asyncness_span }); + error = true; + } + + for attr in tcx.get_attrs(main_def_id, sym::track_caller) { + tcx.sess.emit_err(errors::TrackCallerOnMain { span: attr.span, annotated: main_span }); + error = true; + } + + if !tcx.codegen_fn_attrs(main_def_id).target_features.is_empty() + // Calling functions with `#[target_feature]` is not unsafe on WASM, see #84988 + && !tcx.sess.target.is_like_wasm + && !tcx.sess.opts.actually_rustdoc + { + tcx.sess.emit_err(errors::TargetFeatureOnMain { main: main_span }); + error = true; + } + + if error { + return; + } + + // Main should have no WC, so empty param env is OK here. + let param_env = ty::ParamEnv::empty(); + let expected_return_type; + if let Some(term_did) = tcx.lang_items().termination() { + let return_ty = main_fnsig.output(); + let return_ty_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span); + if !return_ty.bound_vars().is_empty() { + tcx.sess.emit_err(errors::MainFunctionReturnTypeGeneric { span: return_ty_span }); + error = true; + } + let return_ty = return_ty.skip_binder(); + let infcx = tcx.infer_ctxt().build(); + let cause = traits::ObligationCause::new( + return_ty_span, + main_diagnostics_def_id, + ObligationCauseCode::MainFunctionType, + ); + let ocx = traits::ObligationCtxt::new(&infcx); + let norm_return_ty = ocx.normalize(&cause, param_env, return_ty); + ocx.register_bound(cause, param_env, norm_return_ty, term_did); + let errors = ocx.select_all_or_error(); + if !errors.is_empty() { + infcx.err_ctxt().report_fulfillment_errors(&errors); + error = true; + } + // now we can take the return type of the given main function + expected_return_type = main_fnsig.output(); + } else { + // standard () main return type + expected_return_type = ty::Binder::dummy(Ty::new_unit(tcx)); + } + + if error { + return; + } + + let se_ty = Ty::new_fn_ptr( + tcx, + expected_return_type.map_bound(|expected_return_type| { + tcx.mk_fn_sig([], expected_return_type, false, hir::Unsafety::Normal, Abi::Rust) + }), + ); + + require_same_types( + tcx, + &ObligationCause::new( + main_span, + main_diagnostics_def_id, + ObligationCauseCode::MainFunctionType, + ), + param_env, + se_ty, + Ty::new_fn_ptr(tcx, main_fnsig), + ); +} + +fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) { + let start_def_id = start_def_id.expect_local(); + let start_id = tcx.hir().local_def_id_to_hir_id(start_def_id); + let start_span = tcx.def_span(start_def_id); + let start_t = tcx.type_of(start_def_id).instantiate_identity(); + match start_t.kind() { + ty::FnDef(..) => { + if let Some(Node::Item(it)) = tcx.hir().find(start_id) { + if let hir::ItemKind::Fn(sig, generics, _) = &it.kind { + let mut error = false; + if !generics.params.is_empty() { + tcx.sess.emit_err(errors::StartFunctionParameters { span: generics.span }); + error = true; + } + if generics.has_where_clause_predicates { + tcx.sess.emit_err(errors::StartFunctionWhere { + span: generics.where_clause_span, + }); + error = true; + } + if let hir::IsAsync::Async = sig.header.asyncness { + let span = tcx.def_span(it.owner_id); + tcx.sess.emit_err(errors::StartAsync { span: span }); + error = true; + } + + let attrs = tcx.hir().attrs(start_id); + for attr in attrs { + if attr.has_name(sym::track_caller) { + tcx.sess.emit_err(errors::StartTrackCaller { + span: attr.span, + start: start_span, + }); + error = true; + } + if attr.has_name(sym::target_feature) + // Calling functions with `#[target_feature]` is + // not unsafe on WASM, see #84988 + && !tcx.sess.target.is_like_wasm + && !tcx.sess.opts.actually_rustdoc + { + tcx.sess.emit_err(errors::StartTargetFeature { + span: attr.span, + start: start_span, + }); + error = true; + } + } + + if error { + return; + } + } + } + + let se_ty = Ty::new_fn_ptr( + tcx, + ty::Binder::dummy(tcx.mk_fn_sig( + [tcx.types.isize, Ty::new_imm_ptr(tcx, Ty::new_imm_ptr(tcx, tcx.types.u8))], + tcx.types.isize, + false, + hir::Unsafety::Normal, + Abi::Rust, + )), + ); + + require_same_types( + tcx, + &ObligationCause::new( + start_span, + start_def_id, + ObligationCauseCode::StartFunctionType, + ), + ty::ParamEnv::empty(), // start should not have any where bounds. + se_ty, + Ty::new_fn_ptr(tcx, tcx.fn_sig(start_def_id).instantiate_identity()), + ); + } + _ => { + span_bug!(start_span, "start has a non-function type: found `{}`", start_t); + } + } +} diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 1805a08bbb2..def7a3a9d88 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -65,6 +65,7 @@ a type parameter). mod check; mod compare_impl_item; pub mod dropck; +mod entry; pub mod intrinsic; pub mod intrinsicck; mod region; @@ -188,7 +189,7 @@ fn missing_items_err( full_impl_span: Span, ) { let missing_items = - missing_items.iter().filter(|trait_item| trait_item.opt_rpitit_info.is_none()); + missing_items.iter().filter(|trait_item| !trait_item.is_impl_trait_in_trait()); let missing_items_msg = missing_items .clone() @@ -408,7 +409,7 @@ fn fn_sig_suggestion<'tcx>( let asyncness = if tcx.asyncness(assoc.def_id).is_async() { output = if let ty::Alias(_, alias_ty) = *output.kind() { tcx.explicit_item_bounds(alias_ty.def_id) - .arg_iter_copied(tcx, alias_ty.args) + .iter_instantiated_copied(tcx, alias_ty.args) .find_map(|(bound, _)| bound.as_projection_clause()?.no_bound_vars()?.term.ty()) .unwrap_or_else(|| { span_bug!( diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 443d072f992..4e194f1c381 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1567,7 +1567,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> { }); for (bound, bound_span) in tcx .explicit_item_bounds(opaque_ty.def_id) - .arg_iter_copied(tcx, opaque_ty.args) + .iter_instantiated_copied(tcx, opaque_ty.args) { let bound = self.wfcx.normalize(bound_span, None, bound); self.wfcx.register_obligations(traits::wf::predicate_obligations( diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 677d94f1731..d7e62457f36 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -99,20 +99,16 @@ use rustc_errors::ErrorGuaranteed; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_fluent_macro::fluent_messages; use rustc_hir as hir; -use rustc_hir::Node; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::middle; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::util; -use rustc_session::{config::EntryFnType, parse::feature_err}; -use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; +use rustc_session::parse::feature_err; use rustc_span::{symbol::sym, Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; -use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, ObligationCtxt}; - -use std::ops::Not; +use rustc_trait_selection::traits::{self, ObligationCause, ObligationCtxt}; use astconv::{AstConv, OnlySelfBounds}; use bounds::Bounds; @@ -177,267 +173,6 @@ fn require_same_types<'tcx>( } } -fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { - let main_fnsig = tcx.fn_sig(main_def_id).instantiate_identity(); - let main_span = tcx.def_span(main_def_id); - - fn main_fn_diagnostics_def_id(tcx: TyCtxt<'_>, def_id: DefId, sp: Span) -> LocalDefId { - if let Some(local_def_id) = def_id.as_local() { - let hir_type = tcx.type_of(local_def_id).instantiate_identity(); - if !matches!(hir_type.kind(), ty::FnDef(..)) { - span_bug!(sp, "main has a non-function type: found `{}`", hir_type); - } - local_def_id - } else { - CRATE_DEF_ID - } - } - - fn main_fn_generics_params_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> { - if !def_id.is_local() { - return None; - } - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); - match tcx.hir().find(hir_id) { - Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => { - generics.params.is_empty().not().then_some(generics.span) - } - _ => { - span_bug!(tcx.def_span(def_id), "main has a non-function type"); - } - } - } - - fn main_fn_where_clauses_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> { - if !def_id.is_local() { - return None; - } - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); - match tcx.hir().find(hir_id) { - Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => { - Some(generics.where_clause_span) - } - _ => { - span_bug!(tcx.def_span(def_id), "main has a non-function type"); - } - } - } - - fn main_fn_asyncness_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> { - if !def_id.is_local() { - return None; - } - Some(tcx.def_span(def_id)) - } - - fn main_fn_return_type_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> { - if !def_id.is_local() { - return None; - } - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); - match tcx.hir().find(hir_id) { - Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. })) => { - Some(fn_sig.decl.output.span()) - } - _ => { - span_bug!(tcx.def_span(def_id), "main has a non-function type"); - } - } - } - - let mut error = false; - let main_diagnostics_def_id = main_fn_diagnostics_def_id(tcx, main_def_id, main_span); - let main_fn_generics = tcx.generics_of(main_def_id); - let main_fn_predicates = tcx.predicates_of(main_def_id); - if main_fn_generics.count() != 0 || !main_fnsig.bound_vars().is_empty() { - let generics_param_span = main_fn_generics_params_span(tcx, main_def_id); - tcx.sess.emit_err(errors::MainFunctionGenericParameters { - span: generics_param_span.unwrap_or(main_span), - label_span: generics_param_span, - }); - error = true; - } else if !main_fn_predicates.predicates.is_empty() { - // generics may bring in implicit predicates, so we skip this check if generics is present. - let generics_where_clauses_span = main_fn_where_clauses_span(tcx, main_def_id); - tcx.sess.emit_err(errors::WhereClauseOnMain { - span: generics_where_clauses_span.unwrap_or(main_span), - generics_span: generics_where_clauses_span, - }); - error = true; - } - - let main_asyncness = tcx.asyncness(main_def_id); - if let hir::IsAsync::Async = main_asyncness { - let asyncness_span = main_fn_asyncness_span(tcx, main_def_id); - tcx.sess.emit_err(errors::MainFunctionAsync { span: main_span, asyncness: asyncness_span }); - error = true; - } - - for attr in tcx.get_attrs(main_def_id, sym::track_caller) { - tcx.sess.emit_err(errors::TrackCallerOnMain { span: attr.span, annotated: main_span }); - error = true; - } - - if !tcx.codegen_fn_attrs(main_def_id).target_features.is_empty() - // Calling functions with `#[target_feature]` is not unsafe on WASM, see #84988 - && !tcx.sess.target.is_like_wasm - && !tcx.sess.opts.actually_rustdoc - { - tcx.sess.emit_err(errors::TargetFeatureOnMain { main: main_span }); - error = true; - } - - if error { - return; - } - - // Main should have no WC, so empty param env is OK here. - let param_env = ty::ParamEnv::empty(); - let expected_return_type; - if let Some(term_did) = tcx.lang_items().termination() { - let return_ty = main_fnsig.output(); - let return_ty_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span); - if !return_ty.bound_vars().is_empty() { - tcx.sess.emit_err(errors::MainFunctionReturnTypeGeneric { span: return_ty_span }); - error = true; - } - let return_ty = return_ty.skip_binder(); - let infcx = tcx.infer_ctxt().build(); - let cause = traits::ObligationCause::new( - return_ty_span, - main_diagnostics_def_id, - ObligationCauseCode::MainFunctionType, - ); - let ocx = traits::ObligationCtxt::new(&infcx); - let norm_return_ty = ocx.normalize(&cause, param_env, return_ty); - ocx.register_bound(cause, param_env, norm_return_ty, term_did); - let errors = ocx.select_all_or_error(); - if !errors.is_empty() { - infcx.err_ctxt().report_fulfillment_errors(&errors); - error = true; - } - // now we can take the return type of the given main function - expected_return_type = main_fnsig.output(); - } else { - // standard () main return type - expected_return_type = ty::Binder::dummy(Ty::new_unit(tcx)); - } - - if error { - return; - } - - let se_ty = Ty::new_fn_ptr( - tcx, - expected_return_type.map_bound(|expected_return_type| { - tcx.mk_fn_sig([], expected_return_type, false, hir::Unsafety::Normal, Abi::Rust) - }), - ); - - require_same_types( - tcx, - &ObligationCause::new( - main_span, - main_diagnostics_def_id, - ObligationCauseCode::MainFunctionType, - ), - param_env, - se_ty, - Ty::new_fn_ptr(tcx, main_fnsig), - ); -} -fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) { - let start_def_id = start_def_id.expect_local(); - let start_id = tcx.hir().local_def_id_to_hir_id(start_def_id); - let start_span = tcx.def_span(start_def_id); - let start_t = tcx.type_of(start_def_id).instantiate_identity(); - match start_t.kind() { - ty::FnDef(..) => { - if let Some(Node::Item(it)) = tcx.hir().find(start_id) { - if let hir::ItemKind::Fn(sig, generics, _) = &it.kind { - let mut error = false; - if !generics.params.is_empty() { - tcx.sess.emit_err(errors::StartFunctionParameters { span: generics.span }); - error = true; - } - if generics.has_where_clause_predicates { - tcx.sess.emit_err(errors::StartFunctionWhere { - span: generics.where_clause_span, - }); - error = true; - } - if let hir::IsAsync::Async = sig.header.asyncness { - let span = tcx.def_span(it.owner_id); - tcx.sess.emit_err(errors::StartAsync { span: span }); - error = true; - } - - let attrs = tcx.hir().attrs(start_id); - for attr in attrs { - if attr.has_name(sym::track_caller) { - tcx.sess.emit_err(errors::StartTrackCaller { - span: attr.span, - start: start_span, - }); - error = true; - } - if attr.has_name(sym::target_feature) - // Calling functions with `#[target_feature]` is - // not unsafe on WASM, see #84988 - && !tcx.sess.target.is_like_wasm - && !tcx.sess.opts.actually_rustdoc - { - tcx.sess.emit_err(errors::StartTargetFeature { - span: attr.span, - start: start_span, - }); - error = true; - } - } - - if error { - return; - } - } - } - - let se_ty = Ty::new_fn_ptr( - tcx, - ty::Binder::dummy(tcx.mk_fn_sig( - [tcx.types.isize, Ty::new_imm_ptr(tcx, Ty::new_imm_ptr(tcx, tcx.types.u8))], - tcx.types.isize, - false, - hir::Unsafety::Normal, - Abi::Rust, - )), - ); - - require_same_types( - tcx, - &ObligationCause::new( - start_span, - start_def_id, - ObligationCauseCode::StartFunctionType, - ), - ty::ParamEnv::empty(), // start should not have any where bounds. - se_ty, - Ty::new_fn_ptr(tcx, tcx.fn_sig(start_def_id).instantiate_identity()), - ); - } - _ => { - span_bug!(start_span, "start has a non-function type: found `{}`", start_t); - } - } -} - -fn check_for_entry_fn(tcx: TyCtxt<'_>) { - match tcx.entry_fn(()) { - Some((def_id, EntryFnType::Main { .. })) => check_main_fn_ty(tcx, def_id), - Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id), - _ => {} - } -} - pub fn provide(providers: &mut Providers) { collect::provide(providers); coherence::provide(providers); @@ -513,7 +248,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { }); check_unused::check_crate(tcx); - check_for_entry_fn(tcx); if let Some(reported) = tcx.sess.has_errors() { Err(reported) } else { Ok(()) } } diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 199cdabb7e9..1ef257e87d6 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -145,7 +145,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc let mut collector = OpaqueTypeLifetimeCollector { tcx, root_def_id: item_def_id.to_def_id(), variances }; let id_args = ty::GenericArgs::identity_for_item(tcx, item_def_id); - for (pred, _) in tcx.explicit_item_bounds(item_def_id).arg_iter_copied(tcx, id_args) { + for (pred, _) in tcx.explicit_item_bounds(item_def_id).iter_instantiated_copied(tcx, id_args) { debug!(?pred); // We only ignore opaque type args if the opaque type is the outermost type. |
