Skip to content

Commit a62dd0e

Browse files
committed
Add min_specialization feature
Currently the only difference between it and `specialization` is that it only allows specializing functions.
1 parent 7cdbc87 commit a62dd0e

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

src/librustc_ast_passes/feature_gate.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -542,15 +542,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
542542
}
543543

544544
fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) {
545-
if let ast::Defaultness::Default(_) = i.kind.defaultness() {
546-
gate_feature_post!(&self, specialization, i.span, "specialization is unstable");
547-
}
548-
549-
match i.kind {
545+
let is_fn = match i.kind {
550546
ast::AssocItemKind::Fn(_, ref sig, _, _) => {
551547
if let (ast::Const::Yes(_), AssocCtxt::Trait) = (sig.header.constness, ctxt) {
552548
gate_feature_post!(&self, const_fn, i.span, "const fn is unstable");
553549
}
550+
true
554551
}
555552
ast::AssocItemKind::TyAlias(_, ref generics, _, ref ty) => {
556553
if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) {
@@ -565,8 +562,19 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
565562
self.check_impl_trait(ty);
566563
}
567564
self.check_gat(generics, i.span);
565+
false
568566
}
569-
_ => {}
567+
_ => false,
568+
};
569+
if let ast::Defaultness::Default(_) = i.kind.defaultness() {
570+
// Limit `min_specialization` to only specializing functions.
571+
gate_feature_fn!(
572+
&self,
573+
|x: &Features| x.specialization || (is_fn && x.min_specialization),
574+
i.span,
575+
sym::specialization,
576+
"specialization is unstable"
577+
);
570578
}
571579
visit::walk_assoc_item(self, i, ctxt)
572580
}

src/librustc_feature/active.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,11 @@ declare_features! (
301301
/// Allows specialization of implementations (RFC 1210).
302302
(active, specialization, "1.7.0", Some(31844), None),
303303

304+
/// A minimal, sound subset of specialization intended to be used by the
305+
/// standard library until the soundness issues with specialization
306+
/// are fixed.
307+
(active, min_specialization, "1.7.0", Some(31844), None),
308+
304309
/// Allows using `#[naked]` on functions.
305310
(active, naked_functions, "1.9.0", Some(32408), None),
306311

src/librustc_trait_selection/traits/specialize/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,9 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
161161

162162
// The feature gate should prevent introducing new specializations, but not
163163
// taking advantage of upstream ones.
164-
if !tcx.features().specialization && (impl1_def_id.is_local() || impl2_def_id.is_local()) {
164+
let features = tcx.features();
165+
let specialization_enabled = features.specialization || features.min_specialization;
166+
if !specialization_enabled && (impl1_def_id.is_local() || impl2_def_id.is_local()) {
165167
return false;
166168
}
167169

0 commit comments

Comments
 (0)