diff options
| author | Michael Goulet <michael@errs.io> | 2023-06-14 05:20:31 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-06-14 05:20:31 +0000 |
| commit | bc78d0cbf1efb76fa6d7c80bb029a4b6d9af92c3 (patch) | |
| tree | 11cfcd0d5104f741f7ba8e5b68a72bbe23b6cab5 /compiler/rustc_hir_analysis | |
| parent | 6330daade9766bbf896495898c2347dc3be6da17 (diff) | |
| download | rust-bc78d0cbf1efb76fa6d7c80bb029a4b6d9af92c3.tar.gz rust-bc78d0cbf1efb76fa6d7c80bb029a4b6d9af92c3.zip | |
Error on unconstrained lifetime in RPITIT
Diffstat (limited to 'compiler/rustc_hir_analysis')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/compare_impl_item.rs | 59 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/impl_wf_check.rs | 17 |
2 files changed, 53 insertions, 23 deletions
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 dce31975dbc..4fbe68b8b6c 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -45,12 +45,7 @@ pub(super) fn compare_impl_method<'tcx>( debug!("compare_impl_method(impl_trait_ref={:?})", impl_trait_ref); let _: Result<_, ErrorGuaranteed> = try { - compare_self_type(tcx, impl_m, trait_m, impl_trait_ref)?; - compare_number_of_generics(tcx, impl_m, trait_m, false)?; - compare_generic_param_kinds(tcx, impl_m, trait_m, false)?; - compare_number_of_method_arguments(tcx, impl_m, trait_m)?; - compare_synthetic_generics(tcx, impl_m, trait_m)?; - compare_asyncness(tcx, impl_m, trait_m)?; + check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, false)?; compare_method_predicate_entailment( tcx, impl_m, @@ -61,6 +56,26 @@ pub(super) fn compare_impl_method<'tcx>( }; } +/// Checks a bunch of different properties of the impl/trait methods for +/// compatibility, such as asyncness, number of argument, self receiver kind, +/// and number of early- and late-bound generics. +fn check_method_is_structurally_compatible<'tcx>( + tcx: TyCtxt<'tcx>, + impl_m: ty::AssocItem, + trait_m: ty::AssocItem, + impl_trait_ref: ty::TraitRef<'tcx>, + delay: bool, +) -> Result<(), ErrorGuaranteed> { + compare_self_type(tcx, impl_m, trait_m, impl_trait_ref, delay)?; + compare_number_of_generics(tcx, impl_m, trait_m, delay)?; + compare_generic_param_kinds(tcx, impl_m, trait_m, delay)?; + compare_number_of_method_arguments(tcx, impl_m, trait_m, delay)?; + compare_synthetic_generics(tcx, impl_m, trait_m, delay)?; + compare_asyncness(tcx, impl_m, trait_m, delay)?; + check_region_bounds_on_impl_item(tcx, impl_m, trait_m, delay)?; + Ok(()) +} + /// This function is best explained by example. Consider a trait with it's implementation: /// /// ```rust @@ -177,9 +192,6 @@ fn compare_method_predicate_entailment<'tcx>( let impl_m_predicates = tcx.predicates_of(impl_m.def_id); let trait_m_predicates = tcx.predicates_of(trait_m.def_id); - // Check region bounds. - check_region_bounds_on_impl_item(tcx, impl_m, trait_m, false)?; - // Create obligations for each predicate declared by the impl // definition in the context of the trait's parameter // environment. We can't just use `impl_env.caller_bounds`, @@ -534,6 +546,7 @@ fn compare_asyncness<'tcx>( tcx: TyCtxt<'tcx>, impl_m: ty::AssocItem, trait_m: ty::AssocItem, + delay: bool, ) -> Result<(), ErrorGuaranteed> { if tcx.asyncness(trait_m.def_id) == hir::IsAsync::Async { match tcx.fn_sig(impl_m.def_id).skip_binder().skip_binder().output().kind() { @@ -544,11 +557,14 @@ fn compare_asyncness<'tcx>( // We don't know if it's ok, but at least it's already an error. } _ => { - return Err(tcx.sess.emit_err(crate::errors::AsyncTraitImplShouldBeAsync { - span: tcx.def_span(impl_m.def_id), - method_name: trait_m.name, - trait_item_span: tcx.hir().span_if_local(trait_m.def_id), - })); + return Err(tcx + .sess + .create_err(crate::errors::AsyncTraitImplShouldBeAsync { + span: tcx.def_span(impl_m.def_id), + method_name: trait_m.name, + trait_item_span: tcx.hir().span_if_local(trait_m.def_id), + }) + .emit_unless(delay)); } }; } @@ -602,9 +618,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( // First, check a few of the same things as `compare_impl_method`, // just so we don't ICE during substitution later. - compare_number_of_generics(tcx, impl_m, trait_m, true)?; - compare_generic_param_kinds(tcx, impl_m, trait_m, true)?; - check_region_bounds_on_impl_item(tcx, impl_m, trait_m, true)?; + check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?; let trait_to_impl_substs = impl_trait_ref.substs; @@ -1097,6 +1111,7 @@ fn compare_self_type<'tcx>( impl_m: ty::AssocItem, trait_m: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, + delay: bool, ) -> Result<(), ErrorGuaranteed> { // Try to give more informative error messages about self typing // mismatches. Note that any mismatch will also be detected @@ -1145,7 +1160,7 @@ fn compare_self_type<'tcx>( } else { err.note_trait_signature(trait_m.name, trait_m.signature(tcx)); } - return Err(err.emit()); + return Err(err.emit_unless(delay)); } (true, false) => { @@ -1166,7 +1181,7 @@ fn compare_self_type<'tcx>( err.note_trait_signature(trait_m.name, trait_m.signature(tcx)); } - return Err(err.emit()); + return Err(err.emit_unless(delay)); } } @@ -1352,6 +1367,7 @@ fn compare_number_of_method_arguments<'tcx>( tcx: TyCtxt<'tcx>, impl_m: ty::AssocItem, trait_m: ty::AssocItem, + delay: bool, ) -> Result<(), ErrorGuaranteed> { let impl_m_fty = tcx.fn_sig(impl_m.def_id); let trait_m_fty = tcx.fn_sig(trait_m.def_id); @@ -1422,7 +1438,7 @@ fn compare_number_of_method_arguments<'tcx>( ), ); - return Err(err.emit()); + return Err(err.emit_unless(delay)); } Ok(()) @@ -1432,6 +1448,7 @@ fn compare_synthetic_generics<'tcx>( tcx: TyCtxt<'tcx>, impl_m: ty::AssocItem, trait_m: ty::AssocItem, + delay: bool, ) -> Result<(), ErrorGuaranteed> { // FIXME(chrisvittal) Clean up this function, list of FIXME items: // 1. Better messages for the span labels @@ -1551,7 +1568,7 @@ fn compare_synthetic_generics<'tcx>( } _ => unreachable!(), } - error_found = Some(err.emit()); + error_found = Some(err.emit_unless(delay)); } } if let Some(reported) = error_found { Err(reported) } else { Ok(()) } diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 612d4ff3df8..5526dd4b007 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -106,10 +106,23 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) if item.defaultness(tcx).has_value() { cgp::parameters_for(&tcx.type_of(def_id).subst_identity(), true) } else { - Vec::new() + vec![] } } - ty::AssocKind::Fn | ty::AssocKind::Const => Vec::new(), + ty::AssocKind::Fn => { + if !tcx.lower_impl_trait_in_trait_to_assoc_ty() + && item.defaultness(tcx).has_value() + && tcx.impl_method_has_trait_impl_trait_tys(item.def_id) + && let Ok(table) = tcx.collect_return_position_impl_trait_in_trait_tys(def_id) + { + table.values().copied().flat_map(|ty| { + cgp::parameters_for(&ty.subst_identity(), true) + }).collect() + } else { + vec![] + } + } + ty::AssocKind::Const => vec![], } }) .collect(); |
