diff options
| author | Josh Stone <jistone@redhat.com> | 2021-04-12 16:03:53 -0700 |
|---|---|---|
| committer | Josh Stone <jistone@redhat.com> | 2021-04-16 11:11:59 -0700 |
| commit | b79af2fcde91abeae805c2dbccfdbf7114bfd47b (patch) | |
| tree | 05a7eed70824bfae0aef053f516fb5a5327824fb | |
| parent | 2faef12b656d40522ca3b4a53b36299b4364e717 (diff) | |
| download | rust-b79af2fcde91abeae805c2dbccfdbf7114bfd47b.tar.gz rust-b79af2fcde91abeae805c2dbccfdbf7114bfd47b.zip | |
Implement #[rustc_skip_array_during_method_dispatch]
| -rw-r--r-- | compiler/rustc_feature/src/builtin_attrs.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/decoder.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/encoder.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/mod.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/trait_def.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/method/probe.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/collect.rs | 13 |
8 files changed, 38 insertions, 1 deletions
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index f286ea7cdec..be3caf709c7 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -540,6 +540,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_main, Normal, template!(Word), "the `#[rustc_main]` attribute is used internally to specify test entry point function", ), + rustc_attr!( + rustc_skip_array_during_method_dispatch, Normal, template!(Word), + "the `#[rustc_skip_array_during_method_dispatch]` attribute is used to exclude a trait \ + from method dispatch when the receiver is an array, for compatibility in editions < 2021." + ), // ========================================================================== // Internal attributes, Testing: diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 3d0a9d553b0..19ae5ce69c1 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -757,6 +757,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { data.paren_sugar, data.has_auto_impl, data.is_marker, + data.skip_array_during_method_dispatch, data.specialization_kind, self.def_path_hash(item_id), ) @@ -767,6 +768,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { false, false, false, + false, ty::trait_def::TraitSpecializationKind::None, self.def_path_hash(item_id), ), diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index a5157854e15..e8f02b8e66f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1422,6 +1422,7 @@ impl EncodeContext<'a, 'tcx> { paren_sugar: trait_def.paren_sugar, has_auto_impl: self.tcx.trait_is_auto(def_id), is_marker: trait_def.is_marker, + skip_array_during_method_dispatch: trait_def.skip_array_during_method_dispatch, specialization_kind: trait_def.specialization_kind, }; diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 7cfb051e703..9f665d5daaa 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -385,6 +385,7 @@ struct TraitData { paren_sugar: bool, has_auto_impl: bool, is_marker: bool, + skip_array_during_method_dispatch: bool, specialization_kind: ty::trait_def::TraitSpecializationKind, } diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 33065bc3a7b..e9b8883f29a 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -35,6 +35,11 @@ pub struct TraitDef { /// and thus `impl`s of it are allowed to overlap. pub is_marker: bool, + /// If `true`, then this trait has the `#[rustc_skip_array_during_method_dispatch]` + /// attribute, indicating that editions before 2021 should not consider this trait + /// during method dispatch if the receiver is an array. + pub skip_array_during_method_dispatch: bool, + /// Used to determine whether the standard library is allowed to specialize /// on this trait. pub specialization_kind: TraitSpecializationKind, @@ -82,6 +87,7 @@ impl<'tcx> TraitDef { paren_sugar: bool, has_auto_impl: bool, is_marker: bool, + skip_array_during_method_dispatch: bool, specialization_kind: TraitSpecializationKind, def_path_hash: DefPathHash, ) -> TraitDef { @@ -91,6 +97,7 @@ impl<'tcx> TraitDef { paren_sugar, has_auto_impl, is_marker, + skip_array_during_method_dispatch, specialization_kind, def_path_hash, } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 52270f0e627..a88bcc5c558 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1030,6 +1030,7 @@ symbols! { rustc_regions, rustc_reservation_impl, rustc_serialize, + rustc_skip_array_during_method_dispatch, rustc_specialization_trait, rustc_stable, rustc_std_internal_symbol, diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 15342235d48..88fd94931e1 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -1461,6 +1461,15 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } TraitCandidate(trait_ref) => { + if let Some(method_name) = self.method_name { + // Some trait methods are excluded for arrays before 2021. + if self_ty.is_array() && !method_name.span.rust_2021() { + let trait_def = self.tcx.trait_def(trait_ref.def_id); + if trait_def.skip_array_during_method_dispatch { + return ProbeResult::NoMatch; + } + } + } let predicate = trait_ref.without_const().to_predicate(self.tcx); let obligation = traits::Obligation::new(cause, self.param_env, predicate); if !self.predicate_may_hold(&obligation) { diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 1477418d5d8..3692642b6e2 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1191,6 +1191,8 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef { } let is_marker = tcx.has_attr(def_id, sym::marker); + let skip_array_during_method_dispatch = + tcx.has_attr(def_id, sym::rustc_skip_array_during_method_dispatch); let spec_kind = if tcx.has_attr(def_id, sym::rustc_unsafe_specialization_marker) { ty::trait_def::TraitSpecializationKind::Marker } else if tcx.has_attr(def_id, sym::rustc_specialization_trait) { @@ -1199,7 +1201,16 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef { ty::trait_def::TraitSpecializationKind::None }; let def_path_hash = tcx.def_path_hash(def_id); - ty::TraitDef::new(def_id, unsafety, paren_sugar, is_auto, is_marker, spec_kind, def_path_hash) + ty::TraitDef::new( + def_id, + unsafety, + paren_sugar, + is_auto, + is_marker, + skip_array_during_method_dispatch, + spec_kind, + def_path_hash, + ) } fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<Span> { |
