Skip to content

Commit 5bac1c9

Browse files
committed
Only inherit const stability for methods of impl const Trait blocks
1 parent 949bdd8 commit 5bac1c9

File tree

5 files changed

+74
-16
lines changed

5 files changed

+74
-16
lines changed

Diff for: compiler/rustc_mir/src/transform/check_consts/validation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -929,7 +929,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
929929
if callee_is_unstable_unmarked {
930930
trace!("callee_is_unstable_unmarked");
931931
// We do not use `const` modifiers for intrinsic "functions", as intrinsics are
932-
// `extern` funtions, and these have way to get marked `const`. So instead we
932+
// `extern` funtions, and these have no way to get marked `const`. So instead we
933933
// use `rustc_const_(un)stable` attributes to mean that the intrinsic is `const`
934934
if self.ccx.is_const_stable_const_fn() || is_intrinsic {
935935
self.check_op(ops::FnCallUnstable(callee, None));

Diff for: compiler/rustc_passes/src/stability.rs

+60-10
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,21 @@ impl InheritDeprecation {
5555
}
5656
}
5757

58+
/// Whether to inherit const stability flags for nested items. In most cases, we do not want to
59+
/// inherit const stability: just because an enclosing `fn` is const-stable does not mean
60+
/// all `extern` imports declared in it should be const-stable! However, trait methods
61+
/// inherit const stability attributes from their parent and do not have their own.
62+
enum InheritConstStability {
63+
Yes,
64+
No,
65+
}
66+
67+
impl InheritConstStability {
68+
fn yes(&self) -> bool {
69+
matches!(self, InheritConstStability::Yes)
70+
}
71+
}
72+
5873
// A private tree-walker for producing an Index.
5974
struct Annotator<'a, 'tcx> {
6075
tcx: TyCtxt<'tcx>,
@@ -75,6 +90,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
7590
item_sp: Span,
7691
kind: AnnotationKind,
7792
inherit_deprecation: InheritDeprecation,
93+
inherit_const_stability: InheritConstStability,
7894
visit_children: F,
7995
) where
8096
F: FnOnce(&mut Self),
@@ -140,6 +156,8 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
140156
const_stab
141157
});
142158

159+
// `impl const Trait for Type` items forward their const stability to their
160+
// immediate children.
143161
if const_stab.is_none() {
144162
debug!("annotate: const_stab not found, parent = {:?}", self.parent_const_stab);
145163
if let Some(parent) = self.parent_const_stab {
@@ -228,7 +246,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
228246
self.recurse_with_stability_attrs(
229247
depr.map(|(d, _)| DeprecationEntry::local(d, hir_id)),
230248
stab,
231-
const_stab,
249+
if inherit_const_stability.yes() { const_stab } else { None },
232250
visit_children,
233251
);
234252
}
@@ -325,6 +343,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
325343
fn visit_item(&mut self, i: &'tcx Item<'tcx>) {
326344
let orig_in_trait_impl = self.in_trait_impl;
327345
let mut kind = AnnotationKind::Required;
346+
let mut const_stab_inherit = InheritConstStability::No;
328347
match i.kind {
329348
// Inherent impls and foreign modules serve only as containers for other items,
330349
// they don't have their own stability. They still can be annotated as unstable
@@ -338,6 +357,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
338357
hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => {
339358
self.in_trait_impl = true;
340359
kind = AnnotationKind::DeprecationProhibited;
360+
const_stab_inherit = InheritConstStability::Yes;
341361
}
342362
hir::ItemKind::Struct(ref sd, _) => {
343363
if let Some(ctor_hir_id) = sd.ctor_hir_id() {
@@ -347,16 +367,23 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
347367
i.span,
348368
AnnotationKind::Required,
349369
InheritDeprecation::Yes,
370+
InheritConstStability::No,
350371
|_| {},
351372
)
352373
}
353374
}
354375
_ => {}
355376
}
356377

357-
self.annotate(i.hir_id, &i.attrs, i.span, kind, InheritDeprecation::Yes, |v| {
358-
intravisit::walk_item(v, i)
359-
});
378+
self.annotate(
379+
i.hir_id,
380+
&i.attrs,
381+
i.span,
382+
kind,
383+
InheritDeprecation::Yes,
384+
const_stab_inherit,
385+
|v| intravisit::walk_item(v, i),
386+
);
360387
self.in_trait_impl = orig_in_trait_impl;
361388
}
362389

@@ -367,6 +394,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
367394
ti.span,
368395
AnnotationKind::Required,
369396
InheritDeprecation::Yes,
397+
InheritConstStability::No,
370398
|v| {
371399
intravisit::walk_trait_item(v, ti);
372400
},
@@ -376,9 +404,17 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
376404
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) {
377405
let kind =
378406
if self.in_trait_impl { AnnotationKind::Prohibited } else { AnnotationKind::Required };
379-
self.annotate(ii.hir_id, &ii.attrs, ii.span, kind, InheritDeprecation::Yes, |v| {
380-
intravisit::walk_impl_item(v, ii);
381-
});
407+
self.annotate(
408+
ii.hir_id,
409+
&ii.attrs,
410+
ii.span,
411+
kind,
412+
InheritDeprecation::Yes,
413+
InheritConstStability::No,
414+
|v| {
415+
intravisit::walk_impl_item(v, ii);
416+
},
417+
);
382418
}
383419

384420
fn visit_variant(&mut self, var: &'tcx Variant<'tcx>, g: &'tcx Generics<'tcx>, item_id: HirId) {
@@ -388,6 +424,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
388424
var.span,
389425
AnnotationKind::Required,
390426
InheritDeprecation::Yes,
427+
InheritConstStability::No,
391428
|v| {
392429
if let Some(ctor_hir_id) = var.data.ctor_hir_id() {
393430
v.annotate(
@@ -396,6 +433,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
396433
var.span,
397434
AnnotationKind::Required,
398435
InheritDeprecation::Yes,
436+
InheritConstStability::No,
399437
|_| {},
400438
);
401439
}
@@ -412,6 +450,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
412450
s.span,
413451
AnnotationKind::Required,
414452
InheritDeprecation::Yes,
453+
InheritConstStability::No,
415454
|v| {
416455
intravisit::walk_struct_field(v, s);
417456
},
@@ -425,6 +464,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
425464
i.span,
426465
AnnotationKind::Required,
427466
InheritDeprecation::Yes,
467+
InheritConstStability::No,
428468
|v| {
429469
intravisit::walk_foreign_item(v, i);
430470
},
@@ -438,6 +478,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
438478
md.span,
439479
AnnotationKind::Required,
440480
InheritDeprecation::Yes,
481+
InheritConstStability::No,
441482
|_| {},
442483
);
443484
}
@@ -451,9 +492,17 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
451492
_ => AnnotationKind::Prohibited,
452493
};
453494

454-
self.annotate(p.hir_id, &p.attrs, p.span, kind, InheritDeprecation::No, |v| {
455-
intravisit::walk_generic_param(v, p);
456-
});
495+
self.annotate(
496+
p.hir_id,
497+
&p.attrs,
498+
p.span,
499+
kind,
500+
InheritDeprecation::No,
501+
InheritConstStability::No,
502+
|v| {
503+
intravisit::walk_generic_param(v, p);
504+
},
505+
);
457506
}
458507
}
459508

@@ -618,6 +667,7 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
618667
krate.item.span,
619668
AnnotationKind::Required,
620669
InheritDeprecation::Yes,
670+
InheritConstStability::No,
621671
|v| intravisit::walk_crate(v, krate),
622672
);
623673
}

Diff for: library/core/src/intrinsics.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1842,6 +1842,7 @@ pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -
18421842
#[inline]
18431843
pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
18441844
extern "rust-intrinsic" {
1845+
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
18451846
fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
18461847
}
18471848

@@ -1926,6 +1927,7 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
19261927
#[inline]
19271928
pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
19281929
extern "rust-intrinsic" {
1930+
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
19291931
fn copy<T>(src: *const T, dst: *mut T, count: usize);
19301932
}
19311933

Diff for: src/test/ui/consts/intrinsic_without_const_stab.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
1-
// check-pass
2-
31
#![feature(intrinsics, staged_api, const_intrinsic_copy)]
42
#![stable(feature = "core", since = "1.6.0")]
53

64
#[stable(feature = "rust1", since = "1.0.0")]
75
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
86
#[inline]
97
pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
8+
// Const stability attributes are not inherited from parent items.
109
extern "rust-intrinsic" {
1110
fn copy<T>(src: *const T, dst: *mut T, count: usize);
1211
}
1312

14-
// Even though the `copy` intrinsic lacks stability attributes, this works, because it
15-
// inherits its stability attributes from its parent. That includes `rustc_const_(un)stable`
16-
// attributes.
1713
unsafe { copy(src, dst, count) }
14+
//~^ ERROR calls in constant functions are limited to constant functions
1815
}
1916

2017
fn main() {}
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
2+
--> $DIR/intrinsic_without_const_stab.rs:13:14
3+
|
4+
LL | unsafe { copy(src, dst, count) }
5+
| ^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0015`.

0 commit comments

Comments
 (0)