diff options
| author | bors <bors@rust-lang.org> | 2023-05-09 08:16:26 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-05-09 08:16:26 +0000 |
| commit | ecd3dbab4ed82abfa05e22069261e565239449cf (patch) | |
| tree | 03ec27f0a1765fca86fd800b41e83c39c0bd529d /compiler/rustc_hir_analysis/src | |
| parent | 7e7483d26e3cec7a44ef00cf7ae6c9c8c918bec6 (diff) | |
| parent | 9d913eb9e4eb2a433e8755e1359c1cccb344ad3f (diff) | |
| download | rust-ecd3dbab4ed82abfa05e22069261e565239449cf.tar.gz rust-ecd3dbab4ed82abfa05e22069261e565239449cf.zip | |
Auto merge of #111380 - Dylan-DPC:rollup-xiptbhn, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #110304 (Add GNU Property Note) - #110504 (Tweak borrow suggestion span) - #110583 (tweak "make mut" spans when assigning to locals) - #110694 (Implement builtin # syntax and use it for offset_of!(...)) - #111120 (Suggest let for possible binding with ty) - #111252 (Min specialization improvements) - #111361 (Update books) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/errors.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs | 34 |
2 files changed, 39 insertions, 4 deletions
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 379a88538a9..6e7eb4f6cdc 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -815,6 +815,15 @@ pub(crate) struct ClosureImplicitHrtb { } #[derive(Diagnostic)] +#[diag(hir_analysis_empty_specialization)] +pub(crate) struct EmptySpecialization { + #[primary_span] + pub span: Span, + #[note] + pub base_impl_span: Span, +} + +#[derive(Diagnostic)] #[diag(hir_analysis_const_specialize)] pub(crate) struct ConstSpecialize { #[primary_span] 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 5cca2dacb5c..e84da2519ae 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 @@ -80,7 +80,7 @@ use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; -use rustc_trait_selection::traits::{self, translate_substs, wf, ObligationCtxt}; +use rustc_trait_selection::traits::{self, translate_substs_with_cause, wf, ObligationCtxt}; pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) { if let Some(node) = parent_specialization_node(tcx, impl_def_id) { @@ -100,12 +100,19 @@ fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId) -> Opti // Implementing a normal trait isn't a specialization. return None; } + if trait_def.is_marker { + // Overlapping marker implementations are not really specializations. + return None; + } Some(impl2_node) } /// Check that `impl1` is a sound specialization #[instrument(level = "debug", skip(tcx))] fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node) { + let span = tcx.def_span(impl1_def_id); + check_has_items(tcx, impl1_def_id, impl2_node, span); + if let Some((impl1_substs, impl2_substs)) = get_impl_substs(tcx, impl1_def_id, impl2_node) { let impl2_def_id = impl2_node.def_id(); debug!(?impl2_def_id, ?impl2_substs); @@ -116,7 +123,6 @@ fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node unconstrained_parent_impl_substs(tcx, impl2_def_id, impl2_substs) }; - let span = tcx.def_span(impl1_def_id); check_constness(tcx, impl1_def_id, impl2_node, span); check_static_lifetimes(tcx, &parent_substs, span); check_duplicate_params(tcx, impl1_substs, &parent_substs, span); @@ -124,6 +130,13 @@ fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node } } +fn check_has_items(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node, span: Span) { + if let Node::Impl(impl2_id) = impl2_node && tcx.associated_item_def_ids(impl1_def_id).is_empty() { + let base_impl_span = tcx.def_span(impl2_id); + tcx.sess.emit_err(errors::EmptySpecialization { span, base_impl_span }); + } +} + /// Check that the specializing impl `impl1` is at least as const as the base /// impl `impl2` fn check_constness(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node, span: Span) { @@ -167,8 +180,21 @@ fn get_impl_substs( ocx.assumed_wf_types(param_env, tcx.def_span(impl1_def_id), impl1_def_id); let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id); - let impl2_substs = - translate_substs(infcx, param_env, impl1_def_id.to_def_id(), impl1_substs, impl2_node); + let impl1_span = tcx.def_span(impl1_def_id); + let impl2_substs = translate_substs_with_cause( + infcx, + param_env, + impl1_def_id.to_def_id(), + impl1_substs, + impl2_node, + |_, span| { + traits::ObligationCause::new( + impl1_span, + impl1_def_id, + traits::ObligationCauseCode::BindingObligation(impl2_node.def_id(), span), + ) + }, + ); let errors = ocx.select_all_or_error(); if !errors.is_empty() { |
