Skip to content

Commit a04d56b

Browse files
committed
Auto merge of rust-lang#117817 - fmease:deny-more-tilde-const, r=fee1-dead
Deny more `~const` trait bounds thereby fixing a family of ICEs (delayed bugs) for `feature(const_trait_impl, effects)` code. As discussed r? `@fee1-dead`
2 parents 2c1b65e + 8ce5d78 commit a04d56b

25 files changed

+444
-134
lines changed

compiler/rustc_ast_passes/messages.ftl

+4-1
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,12 @@ ast_passes_static_without_body =
218218
.suggestion = provide a definition for the static
219219
220220
ast_passes_tilde_const_disallowed = `~const` is not allowed here
221-
.trait = trait objects cannot have `~const` trait bounds
222221
.closure = closures cannot have `~const` trait bounds
223222
.function = this function is not `const`, so it cannot have `~const` trait bounds
223+
.trait = this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
224+
.impl = this impl is not `const`, so it cannot have `~const` trait bounds
225+
.object = trait objects cannot have `~const` trait bounds
226+
.item = this item cannot have `~const` trait bounds
224227
225228
ast_passes_trait_fn_const =
226229
functions in traits cannot be declared const

compiler/rustc_ast_passes/src/ast_validation.rs

+30-45
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ enum SelfSemantic {
4040
enum DisallowTildeConstContext<'a> {
4141
TraitObject,
4242
Fn(FnKind<'a>),
43+
Trait(Span),
44+
Impl(Span),
45+
Item,
4346
}
4447

4548
struct AstValidator<'a> {
@@ -110,18 +113,6 @@ impl<'a> AstValidator<'a> {
110113
self.disallow_tilde_const = old;
111114
}
112115

113-
fn with_tilde_const_allowed(&mut self, f: impl FnOnce(&mut Self)) {
114-
self.with_tilde_const(None, f)
115-
}
116-
117-
fn with_banned_tilde_const(
118-
&mut self,
119-
ctx: DisallowTildeConstContext<'a>,
120-
f: impl FnOnce(&mut Self),
121-
) {
122-
self.with_tilde_const(Some(ctx), f)
123-
}
124-
125116
fn check_type_alias_where_clause_location(
126117
&mut self,
127118
ty_alias: &TyAlias,
@@ -173,7 +164,7 @@ impl<'a> AstValidator<'a> {
173164
self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t))
174165
}
175166
TyKind::TraitObject(..) => self
176-
.with_banned_tilde_const(DisallowTildeConstContext::TraitObject, |this| {
167+
.with_tilde_const(Some(DisallowTildeConstContext::TraitObject), |this| {
177168
visit::walk_ty(this, t)
178169
}),
179170
TyKind::Path(qself, path) => {
@@ -845,11 +836,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
845836

846837
this.visit_vis(&item.vis);
847838
this.visit_ident(item.ident);
848-
if let Const::Yes(_) = constness {
849-
this.with_tilde_const_allowed(|this| this.visit_generics(generics));
850-
} else {
851-
this.visit_generics(generics);
852-
}
839+
let disallowed = matches!(constness, Const::No)
840+
.then(|| DisallowTildeConstContext::Impl(item.span));
841+
this.with_tilde_const(disallowed, |this| this.visit_generics(generics));
853842
this.visit_trait_ref(t);
854843
this.visit_ty(self_ty);
855844

@@ -863,10 +852,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
863852
polarity,
864853
defaultness,
865854
constness,
866-
generics: _,
855+
generics,
867856
of_trait: None,
868857
self_ty,
869-
items: _,
858+
items,
870859
}) => {
871860
let error =
872861
|annotation_span, annotation, only_trait: bool| errors::InherentImplCannot {
@@ -898,6 +887,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
898887
if let &Const::Yes(span) = constness {
899888
self.err_handler().emit_err(error(span, "`const`", true));
900889
}
890+
891+
self.visit_vis(&item.vis);
892+
self.visit_ident(item.ident);
893+
self.with_tilde_const(None, |this| this.visit_generics(generics));
894+
self.visit_ty(self_ty);
895+
walk_list!(self, visit_assoc_item, items, AssocCtxt::Impl);
896+
walk_list!(self, visit_attribute, &item.attrs);
897+
return; // Avoid visiting again.
901898
}
902899
ItemKind::Fn(box Fn { defaultness, sig, generics, body }) => {
903900
self.check_defaultness(item.span, *defaultness);
@@ -978,8 +975,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
978975
// context for the supertraits.
979976
this.visit_vis(&item.vis);
980977
this.visit_ident(item.ident);
981-
this.visit_generics(generics);
982-
this.with_tilde_const_allowed(|this| {
978+
let disallowed =
979+
(!is_const_trait).then(|| DisallowTildeConstContext::Trait(item.span));
980+
this.with_tilde_const(disallowed, |this| {
981+
this.visit_generics(generics);
983982
walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits)
984983
});
985984
walk_list!(this, visit_assoc_item, items, AssocCtxt::Trait);
@@ -999,16 +998,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
999998
}
1000999
}
10011000
ItemKind::Struct(vdata, generics) => match vdata {
1002-
// Duplicating the `Visitor` logic allows catching all cases
1003-
// of `Anonymous(Struct, Union)` outside of a field struct or union.
1004-
//
1005-
// Inside `visit_ty` the validator catches every `Anonymous(Struct, Union)` it
1006-
// encounters, and only on `ItemKind::Struct` and `ItemKind::Union`
1007-
// it uses `visit_ty_common`, which doesn't contain that specific check.
10081001
VariantData::Struct(fields, ..) => {
10091002
self.visit_vis(&item.vis);
10101003
self.visit_ident(item.ident);
10111004
self.visit_generics(generics);
1005+
// Permit `Anon{Struct,Union}` as field type.
10121006
walk_list!(self, visit_struct_field_def, fields);
10131007
walk_list!(self, visit_attribute, &item.attrs);
10141008
return;
@@ -1024,6 +1018,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10241018
self.visit_vis(&item.vis);
10251019
self.visit_ident(item.ident);
10261020
self.visit_generics(generics);
1021+
// Permit `Anon{Struct,Union}` as field type.
10271022
walk_list!(self, visit_struct_field_def, fields);
10281023
walk_list!(self, visit_attribute, &item.attrs);
10291024
return;
@@ -1212,15 +1207,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
12121207
if let Some(reason) = &self.disallow_tilde_const =>
12131208
{
12141209
let reason = match reason {
1215-
DisallowTildeConstContext::TraitObject => {
1216-
errors::TildeConstReason::TraitObject
1217-
}
12181210
DisallowTildeConstContext::Fn(FnKind::Closure(..)) => {
12191211
errors::TildeConstReason::Closure
12201212
}
12211213
DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => {
12221214
errors::TildeConstReason::Function { ident: ident.span }
12231215
}
1216+
&DisallowTildeConstContext::Trait(span) => errors::TildeConstReason::Trait { span },
1217+
&DisallowTildeConstContext::Impl(span) => errors::TildeConstReason::Impl { span },
1218+
DisallowTildeConstContext::TraitObject => {
1219+
errors::TildeConstReason::TraitObject
1220+
}
1221+
DisallowTildeConstContext::Item => errors::TildeConstReason::Item,
12241222
};
12251223
self.err_handler()
12261224
.emit_err(errors::TildeConstDisallowed { span: bound.span(), reason });
@@ -1328,7 +1326,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13281326
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)) if self.in_const_trait_or_impl);
13291327

13301328
let disallowed = (!tilde_const_allowed).then(|| DisallowTildeConstContext::Fn(fk));
1331-
13321329
self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
13331330
}
13341331

@@ -1397,18 +1394,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13971394
}
13981395

13991396
match &item.kind {
1400-
AssocItemKind::Type(box TyAlias { generics, bounds, ty, .. })
1401-
if ctxt == AssocCtxt::Trait =>
1402-
{
1403-
self.visit_vis(&item.vis);
1404-
self.visit_ident(item.ident);
1405-
walk_list!(self, visit_attribute, &item.attrs);
1406-
self.with_tilde_const_allowed(|this| {
1407-
this.visit_generics(generics);
1408-
walk_list!(this, visit_param_bound, bounds, BoundKind::Bound);
1409-
});
1410-
walk_list!(self, visit_ty, ty);
1411-
}
14121397
AssocItemKind::Fn(box Fn { sig, generics, body, .. })
14131398
if self.in_const_trait_or_impl
14141399
|| ctxt == AssocCtxt::Trait
@@ -1552,7 +1537,7 @@ pub fn check_crate(
15521537
in_const_trait_or_impl: false,
15531538
has_proc_macro_decls: false,
15541539
outer_impl_trait: None,
1555-
disallow_tilde_const: None,
1540+
disallow_tilde_const: Some(DisallowTildeConstContext::Item),
15561541
is_impl_trait_banned: false,
15571542
lint_buffer: lints,
15581543
};

compiler/rustc_ast_passes/src/errors.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -551,15 +551,27 @@ pub struct TildeConstDisallowed {
551551

552552
#[derive(Subdiagnostic)]
553553
pub enum TildeConstReason {
554-
#[note(ast_passes_trait)]
555-
TraitObject,
556554
#[note(ast_passes_closure)]
557555
Closure,
558556
#[note(ast_passes_function)]
559557
Function {
560558
#[primary_span]
561559
ident: Span,
562560
},
561+
#[note(ast_passes_trait)]
562+
Trait {
563+
#[primary_span]
564+
span: Span,
565+
},
566+
#[note(ast_passes_impl)]
567+
Impl {
568+
#[primary_span]
569+
span: Span,
570+
},
571+
#[note(ast_passes_object)]
572+
TraitObject,
573+
#[note(ast_passes_item)]
574+
Item,
563575
}
564576

565577
#[derive(Diagnostic)]

tests/ui/generic-const-items/const-trait-impl.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
#![allow(incomplete_features)]
88
#![crate_type = "lib"]
99

10-
// FIXME(generic_const_items): Interpret `~const` as always-const.
11-
const CREATE<T: ~const Create>: T = T::create();
10+
// FIXME(generic_const_items, effects): Introduce `const` bounds to make this work.
11+
const CREATE<T: Create>: T = T::create();
1212

1313
pub const K0: i32 = CREATE::<i32>;
1414
pub const K1: i32 = CREATE; // arg inferred

tests/ui/generic-const-items/const-trait-impl.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0015]: cannot call non-const fn `<T as Create>::create` in constants
2-
--> $DIR/const-trait-impl.rs:11:37
2+
--> $DIR/const-trait-impl.rs:11:30
33
|
4-
LL | const CREATE<T: ~const Create>: T = T::create();
5-
| ^^^^^^^^^^^
4+
LL | const CREATE<T: Create>: T = T::create();
5+
| ^^^^^^^^^^^
66
|
77
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
88

tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
error: `~const` is not allowed here
2+
--> $DIR/assoc-type-const-bound-usage.rs:7:17
3+
|
4+
LL | type Assoc: ~const Foo;
5+
| ^^^^^^^^^^
6+
|
7+
= note: this item cannot have `~const` trait bounds
8+
19
error[E0308]: mismatched types
210
--> $DIR/assoc-type-const-bound-usage.rs:12:5
311
|
@@ -7,6 +15,6 @@ LL | <T as Foo>::Assoc::foo();
715
= note: expected constant `host`
816
found constant `true`
917

10-
error: aborting due to previous error
18+
error: aborting due to 2 previous errors
1119

1220
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
1+
error: `~const` is not allowed here
2+
--> $DIR/assoc-type.rs:17:15
3+
|
4+
LL | type Bar: ~const std::ops::Add;
5+
| ^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: this item cannot have `~const` trait bounds
8+
19
error: ~const can only be applied to `#[const_trait]` traits
210
--> $DIR/assoc-type.rs:17:22
311
|
412
LL | type Bar: ~const std::ops::Add;
513
| ^^^^^^^^^^^^^
614

7-
error: aborting due to previous error
15+
error: aborting due to 2 previous errors
816

tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const-bound-on-not-const-associated-fn.rs renamed to tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(const_trait_impl, effects)]
1+
#![feature(const_trait_impl)]
22

33
#[const_trait]
44
trait MyTrait {
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
1-
error[E0493]: destructor of `T` cannot be evaluated at compile-time
2-
--> $DIR/const-drop.rs:19:32
1+
error: `~const` is not allowed here
2+
--> $DIR/const-drop.rs:67:38
33
|
4-
LL | const fn a<T: ~const Destruct>(_: T) {}
5-
| ^ - value is dropped here
6-
| |
7-
| the destructor for this type cannot be evaluated in constant functions
8-
9-
error[E0493]: destructor of `S<'_>` cannot be evaluated at compile-time
10-
--> $DIR/const-drop.rs:24:13
4+
LL | pub struct ConstDropWithBound<T: ~const SomeTrait>(pub core::marker::PhantomData<T>);
5+
| ^^^^^^^^^^^^^^^^
116
|
12-
LL | let _ = S(&mut c);
13-
| ^^^^^^^^^- value is dropped here
14-
| |
15-
| the destructor for this type cannot be evaluated in constant functions
7+
= note: this item cannot have `~const` trait bounds
168

17-
error: aborting due to 2 previous errors
9+
error: aborting due to previous error
1810

19-
For more information about this error, try `rustc --explain E0493`.

tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.rs

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ mod t {
6363
fn foo() {}
6464
}
6565

66+
// FIXME(effects): This should be a `const` bound instead of a `~const` one.
6667
pub struct ConstDropWithBound<T: ~const SomeTrait>(pub core::marker::PhantomData<T>);
6768

6869
impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
1-
error[E0493]: destructor of `T` cannot be evaluated at compile-time
2-
--> $DIR/const-drop.rs:19:32
1+
error: `~const` is not allowed here
2+
--> $DIR/const-drop.rs:67:38
33
|
4-
LL | const fn a<T: ~const Destruct>(_: T) {}
5-
| ^ - value is dropped here
6-
| |
7-
| the destructor for this type cannot be evaluated in constant functions
8-
9-
error[E0493]: destructor of `S<'_>` cannot be evaluated at compile-time
10-
--> $DIR/const-drop.rs:24:13
4+
LL | pub struct ConstDropWithBound<T: ~const SomeTrait>(pub core::marker::PhantomData<T>);
5+
| ^^^^^^^^^^^^^^^^
116
|
12-
LL | let _ = S(&mut c);
13-
| ^^^^^^^^^- value is dropped here
14-
| |
15-
| the destructor for this type cannot be evaluated in constant functions
7+
= note: this item cannot have `~const` trait bounds
168

17-
error: aborting due to 2 previous errors
9+
error: aborting due to previous error
1810

19-
For more information about this error, try `rustc --explain E0493`.

tests/ui/rfcs/rfc-2632-const-trait-impl/issue-90052.rs

-9
This file was deleted.

tests/ui/rfcs/rfc-2632-const-trait-impl/issue-90052.stderr

-14
This file was deleted.

tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,7 @@ trait Bar {
1818
fn bar();
1919
}
2020

21-
// bgr360: I was only able to exercise the code path that raises the
22-
// "missing ~const qualifier" error by making this base impl non-const, even
23-
// though that doesn't really make sense to do. As seen below, if the base impl
24-
// is made const, rustc fails earlier with an overlapping impl failure.
25-
impl<T> Bar for T
21+
impl<T> const Bar for T
2622
where
2723
T: ~const Foo,
2824
{

0 commit comments

Comments
 (0)