diff options
| author | Matthew Jasper <mjjasper1@gmail.com> | 2020-02-08 17:07:36 +0000 |
|---|---|---|
| committer | Matthew Jasper <mjjasper1@gmail.com> | 2020-03-15 12:44:25 +0000 |
| commit | a62dd0e3bab098a4dd389a7942c2f4861f83443f (patch) | |
| tree | d8ffe85bca461e17f81cf4f26517bfd12b9d5e00 | |
| parent | 7cdbc87a49b0b705a41a004a6d486b0952521ae7 (diff) | |
| download | rust-a62dd0e3bab098a4dd389a7942c2f4861f83443f.tar.gz rust-a62dd0e3bab098a4dd389a7942c2f4861f83443f.zip | |
Add `min_specialization` feature
Currently the only difference between it and `specialization` is that it only allows specializing functions.
| -rw-r--r-- | src/librustc_ast_passes/feature_gate.rs | 20 | ||||
| -rw-r--r-- | src/librustc_feature/active.rs | 5 | ||||
| -rw-r--r-- | src/librustc_trait_selection/traits/specialize/mod.rs | 4 |
3 files changed, 22 insertions, 7 deletions
diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index 5f36149451d..f9f4c3efeb6 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -542,15 +542,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) { - if let ast::Defaultness::Default(_) = i.kind.defaultness() { - gate_feature_post!(&self, specialization, i.span, "specialization is unstable"); - } - - match i.kind { + let is_fn = match i.kind { ast::AssocItemKind::Fn(_, ref sig, _, _) => { if let (ast::Const::Yes(_), AssocCtxt::Trait) = (sig.header.constness, ctxt) { gate_feature_post!(&self, const_fn, i.span, "const fn is unstable"); } + true } ast::AssocItemKind::TyAlias(_, ref generics, _, ref ty) => { if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) { @@ -565,8 +562,19 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { self.check_impl_trait(ty); } self.check_gat(generics, i.span); + false } - _ => {} + _ => false, + }; + if let ast::Defaultness::Default(_) = i.kind.defaultness() { + // Limit `min_specialization` to only specializing functions. + gate_feature_fn!( + &self, + |x: &Features| x.specialization || (is_fn && x.min_specialization), + i.span, + sym::specialization, + "specialization is unstable" + ); } visit::walk_assoc_item(self, i, ctxt) } diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 3a0fc6f8da1..9f1fee8fc09 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -301,6 +301,11 @@ declare_features! ( /// Allows specialization of implementations (RFC 1210). (active, specialization, "1.7.0", Some(31844), None), + /// A minimal, sound subset of specialization intended to be used by the + /// standard library until the soundness issues with specialization + /// are fixed. + (active, min_specialization, "1.7.0", Some(31844), None), + /// Allows using `#[naked]` on functions. (active, naked_functions, "1.9.0", Some(32408), None), diff --git a/src/librustc_trait_selection/traits/specialize/mod.rs b/src/librustc_trait_selection/traits/specialize/mod.rs index d1d4a58fdf2..770253e635e 100644 --- a/src/librustc_trait_selection/traits/specialize/mod.rs +++ b/src/librustc_trait_selection/traits/specialize/mod.rs @@ -161,7 +161,9 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, // The feature gate should prevent introducing new specializations, but not // taking advantage of upstream ones. - if !tcx.features().specialization && (impl1_def_id.is_local() || impl2_def_id.is_local()) { + let features = tcx.features(); + let specialization_enabled = features.specialization || features.min_specialization; + if !specialization_enabled && (impl1_def_id.is_local() || impl2_def_id.is_local()) { return false; } |
