Skip to content

Commit 5f63932

Browse files
committed
Implement MVP for opaque generic const arguments
This is meant to be the interim successor to generic const expressions. Essentially, const item RHS's will be allowed to do arbitrary const operations using generics. The limitation is that these const items will be treated opaquely, like ADTs in nominal typing, such that uses of them will only be equal if the same const item is referenced. In other words, two const items with the exact same RHS will not be considered equal. I also added some logic to check feature gates that depend on others being enabled (like oGCA depending on mGCA). = Coherence = During coherence, OGCA consts should be normalized ambiguously because they are opaque but eventually resolved to a real value. We don't want two OGCAs that have the same value to be treated as distinct for coherence purposes. (Just like opaque types.) This actually doesn't work yet because there are pre-existing fundamental issues with equate relations involving consts that need to be normalized. The problem is that we normalize only one layer of the const item and don't actually process the resulting anon const. Normally the created inference variable should be handled, which in this case would cause us to hit the anon const, but that's not happening. Specifically, `visit_const` on `Generalizer` should be updated to be similar to `visit_ty`.
1 parent c7f5f3e commit 5f63932

48 files changed

Lines changed: 688 additions & 49 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 345 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,345 @@
1+
ast_passes_abi_cannot_be_coroutine =
2+
functions with the {$abi} ABI cannot be `{$coroutine_kind_str}`
3+
.suggestion = remove the `{$coroutine_kind_str}` keyword from this definition
4+
5+
ast_passes_abi_custom_safe_foreign_function =
6+
foreign functions with the "custom" ABI cannot be safe
7+
.suggestion = remove the `safe` keyword from this definition
8+
9+
ast_passes_abi_custom_safe_function =
10+
functions with the "custom" ABI must be unsafe
11+
.suggestion = add the `unsafe` keyword to this definition
12+
13+
ast_passes_abi_must_not_have_parameters_or_return_type=
14+
invalid signature for `extern {$abi}` function
15+
.note = functions with the {$abi} ABI cannot have any parameters or return type
16+
.suggestion = remove the parameters and return type
17+
18+
ast_passes_abi_must_not_have_return_type=
19+
invalid signature for `extern {$abi}` function
20+
.note = functions with the {$abi} ABI cannot have a return type
21+
.help = remove the return type
22+
23+
ast_passes_abi_x86_interrupt =
24+
invalid signature for `extern "x86-interrupt"` function
25+
.note = functions with the "x86-interrupt" ABI must be have either 1 or 2 parameters (but found {$param_count})
26+
27+
ast_passes_assoc_const_without_body =
28+
associated constant in `impl` without body
29+
.suggestion = provide a definition for the constant
30+
31+
ast_passes_assoc_fn_without_body =
32+
associated function in `impl` without body
33+
.suggestion = provide a definition for the function
34+
35+
ast_passes_assoc_type_without_body =
36+
associated type in `impl` without body
37+
.suggestion = provide a definition for the type
38+
39+
ast_passes_async_fn_in_const_trait_or_trait_impl =
40+
async functions are not allowed in `const` {$context ->
41+
[trait_impl] trait impls
42+
[impl] impls
43+
*[trait] traits
44+
}
45+
.label = associated functions of `const` cannot be declared `async`
46+
47+
ast_passes_at_least_one_trait = at least one trait must be specified
48+
49+
ast_passes_auto_generic = auto traits cannot have generic parameters
50+
.label = auto trait cannot have generic parameters
51+
.suggestion = remove the parameters
52+
53+
ast_passes_auto_items = auto traits cannot have associated items
54+
.label = {ast_passes_auto_items}
55+
.suggestion = remove the associated items
56+
57+
ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetime bounds
58+
.label = {ast_passes_auto_super_lifetime}
59+
.suggestion = remove the super traits or lifetime bounds
60+
61+
ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block
62+
.cannot_have = cannot have a body
63+
.invalid = the invalid body
64+
.existing = `extern` blocks define existing foreign {$kind}s and {$kind}s inside of them cannot have a body
65+
66+
ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect
67+
68+
ast_passes_c_variadic_bad_extern = `...` is not supported for `extern "{$abi}"` functions
69+
.label = `extern "{$abi}"` because of this
70+
.help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
71+
72+
ast_passes_c_variadic_bad_naked_extern = `...` is not supported for `extern "{$abi}"` naked functions
73+
.label = `extern "{$abi}"` because of this
74+
.help = C-variadic function must have a compatible calling convention
75+
76+
ast_passes_c_variadic_must_be_unsafe =
77+
functions with a C variable argument list must be unsafe
78+
.suggestion = add the `unsafe` keyword to this definition
79+
80+
ast_passes_c_variadic_no_extern = `...` is not supported for non-extern functions
81+
.help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
82+
83+
ast_passes_c_variadic_not_supported = the `{$target}` target does not support c-variadic functions
84+
85+
ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic
86+
.const = `const` because of this
87+
.variadic = C-variadic because of this
88+
89+
ast_passes_const_and_coroutine = functions cannot be both `const` and `{$coroutine_kind}`
90+
.const = `const` because of this
91+
.coroutine = `{$coroutine_kind}` because of this
92+
.label = {""}
93+
94+
ast_passes_const_auto_trait = auto traits cannot be const
95+
.help = remove the `const` keyword
96+
97+
ast_passes_const_bound_trait_object = const trait bounds are not allowed in trait object types
98+
99+
ast_passes_const_without_body =
100+
free constant item without body
101+
.suggestion = provide a definition for the constant
102+
103+
ast_passes_constraint_on_negative_bound =
104+
associated type constraints not allowed on negative bounds
105+
106+
ast_passes_coroutine_and_c_variadic = functions cannot be both `{$coroutine_kind}` and C-variadic
107+
.const = `{$coroutine_kind}` because of this
108+
.variadic = C-variadic because of this
109+
110+
ast_passes_equality_in_where = equality constraints are not yet supported in `where` clauses
111+
.label = not supported
112+
.suggestion = if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax
113+
.suggestion_path = if `{$trait_segment}::{$potential_assoc}` is an associated type you're trying to set, use the associated type binding syntax
114+
.note = see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
115+
116+
ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block
117+
118+
ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have `{$kw}` qualifier
119+
.label = in this `extern` block
120+
.suggestion = remove the `{$kw}` qualifier
121+
122+
ast_passes_extern_invalid_safety = items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers
123+
.suggestion = add `unsafe` to this `extern` block
124+
125+
ast_passes_extern_item_ascii = items in `extern` blocks cannot use non-ascii identifiers
126+
.label = in this `extern` block
127+
.note = this limitation may be lifted in the future; see issue #83942 <https://github.com/rust-lang/rust/issues/83942> for more information
128+
129+
ast_passes_extern_keyword_link = for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
130+
131+
ast_passes_extern_types_cannot = `type`s inside `extern` blocks cannot have {$descr}
132+
.suggestion = remove the {$remove_descr}
133+
.label = `extern` block begins here
134+
135+
ast_passes_extern_without_abi = `extern` declarations without an explicit ABI are disallowed
136+
.suggestion = specify an ABI
137+
.help = prior to Rust 2024, a default ABI was inferred
138+
139+
ast_passes_extern_without_abi_sugg = `extern` declarations without an explicit ABI are deprecated
140+
.label = ABI should be specified here
141+
.suggestion = explicitly specify the {$default_abi} ABI
142+
143+
ast_passes_feature_on_non_nightly = `#![feature]` may not be used on the {$channel} release channel
144+
.suggestion = remove the attribute
145+
.stable_since = the feature `{$name}` has been stable since `{$since}` and no longer requires an attribute to enable
146+
147+
ast_passes_fieldless_union = unions cannot have zero fields
148+
149+
ast_passes_fn_body_extern = incorrect function inside `extern` block
150+
.cannot_have = cannot have a body
151+
.suggestion = remove the invalid body
152+
.help = you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block
153+
.label = `extern` blocks define existing foreign functions and functions inside of them cannot have a body
154+
155+
ast_passes_fn_param_c_var_args_not_last =
156+
`...` must be the last argument of a C-variadic function
157+
158+
ast_passes_fn_param_doc_comment =
159+
documentation comments cannot be applied to function parameters
160+
.label = doc comments are not allowed here
161+
162+
ast_passes_fn_param_forbidden_attr =
163+
allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters
164+
165+
ast_passes_fn_param_forbidden_self =
166+
`self` parameter is only allowed in associated functions
167+
.label = not semantically valid as function parameter
168+
.note = associated functions are those in `impl` or `trait` definitions
169+
170+
ast_passes_fn_param_too_many =
171+
function can not have more than {$max_num_args} arguments
172+
173+
ast_passes_fn_ptr_invalid_safety = function pointers cannot be declared with `safe` safety qualifier
174+
.suggestion = remove safe from this item
175+
176+
ast_passes_fn_without_body =
177+
free function without a body
178+
.suggestion = provide a definition for the function
179+
180+
ast_passes_forbidden_bound =
181+
bounds cannot be used in this context
182+
183+
ast_passes_forbidden_const_param =
184+
late-bound const parameters cannot be used currently
185+
186+
ast_passes_forbidden_default =
187+
`default` is only allowed on items in trait impls
188+
.label = `default` because of this
189+
190+
ast_passes_forbidden_non_lifetime_param =
191+
only lifetime parameters can be used in this context
192+
193+
ast_passes_generic_before_constraints = generic arguments must come before the first constraint
194+
.constraints = {$constraint_len ->
195+
[one] constraint
196+
*[other] constraints
197+
}
198+
.args = generic {$args_len ->
199+
[one] argument
200+
*[other] arguments
201+
}
202+
.empty_string = {""},
203+
.suggestion = move the {$constraint_len ->
204+
[one] constraint
205+
*[other] constraints
206+
} after the generic {$args_len ->
207+
[one] argument
208+
*[other] arguments
209+
}
210+
211+
ast_passes_generic_default_trailing = generic parameters with a default must be trailing
212+
213+
ast_passes_impl_fn_const =
214+
redundant `const` fn marker in const impl
215+
.parent_constness = this declares all associated functions implicitly const
216+
.label = remove the `const`
217+
218+
ast_passes_incompatible_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed
219+
.help = remove one of these features
220+
221+
ast_passes_item_invalid_safety = items outside of `unsafe extern {"{ }"}` cannot be declared with `safe` safety qualifier
222+
.suggestion = remove safe from this item
223+
224+
ast_passes_item_underscore = `{$kind}` items in this context need a name
225+
.label = `_` is not a valid name for this `{$kind}` item
226+
227+
ast_passes_match_arm_with_no_body =
228+
`match` arm with no body
229+
.suggestion = add a body after the pattern
230+
231+
ast_passes_missing_dependent_features = `{$parent}` requires {$missing} to be enabled
232+
.help = enable all of these features
233+
234+
ast_passes_missing_unsafe_on_extern = extern blocks must be unsafe
235+
.suggestion = needs `unsafe` before the extern keyword
236+
237+
ast_passes_missing_unsafe_on_extern_lint = extern blocks should be unsafe
238+
.suggestion = needs `unsafe` before the extern keyword
239+
240+
ast_passes_module_nonascii = trying to load file for module `{$name}` with non-ascii identifier name
241+
.help = consider using the `#[path]` attribute to specify filesystem path
242+
243+
ast_passes_negative_bound_not_supported =
244+
negative bounds are not supported
245+
246+
ast_passes_negative_bound_with_parenthetical_notation =
247+
parenthetical notation may not be used for negative bounds
248+
249+
ast_passes_nested_impl_trait = nested `impl Trait` is not allowed
250+
.outer = outer `impl Trait`
251+
.inner = nested `impl Trait` here
252+
253+
ast_passes_nested_lifetimes = nested quantification of lifetimes
254+
255+
ast_passes_nomangle_ascii = `#[no_mangle]` requires ASCII identifier
256+
257+
ast_passes_obsolete_auto = `impl Trait for .. {"{}"}` is an obsolete syntax
258+
.help = use `auto trait Trait {"{}"}` instead
259+
260+
ast_passes_out_of_order_params = {$param_ord} parameters must be declared prior to {$max_param} parameters
261+
.suggestion = reorder the parameters: lifetimes, then consts and types
262+
263+
ast_passes_pattern_in_bodiless = patterns aren't allowed in functions without bodies
264+
.label = pattern not allowed in function without body
265+
266+
ast_passes_pattern_in_fn_pointer = patterns aren't allowed in function pointer types
267+
268+
ast_passes_pattern_in_foreign = patterns aren't allowed in foreign function declarations
269+
.label = pattern not allowed in foreign function
270+
271+
ast_passes_precise_capturing_duplicated = duplicate `use<...>` precise capturing syntax
272+
.label = second `use<...>` here
273+
274+
ast_passes_precise_capturing_not_allowed_here = `use<...>` precise capturing syntax not allowed in {$loc}
275+
276+
ast_passes_scalable_vector_not_tuple_struct = scalable vectors must be tuple structs
277+
278+
ast_passes_static_without_body =
279+
free static item without body
280+
.suggestion = provide a definition for the static
281+
282+
ast_passes_tilde_const_disallowed = `[const]` is not allowed here
283+
.closure = closures cannot have `[const]` trait bounds
284+
.function = this function is not `const`, so it cannot have `[const]` trait bounds
285+
.trait = this trait is not `const`, so it cannot have `[const]` trait bounds
286+
.trait_impl = this impl is not `const`, so it cannot have `[const]` trait bounds
287+
.impl = inherent impls cannot have `[const]` trait bounds
288+
.trait_assoc_ty = associated types in non-`const` traits cannot have `[const]` trait bounds
289+
.trait_impl_assoc_ty = associated types in non-const impls cannot have `[const]` trait bounds
290+
.inherent_assoc_ty = inherent associated types cannot have `[const]` trait bounds
291+
.struct = structs cannot have `[const]` trait bounds
292+
.enum = enums cannot have `[const]` trait bounds
293+
.union = unions cannot have `[const]` trait bounds
294+
.anon_const = anonymous constants cannot have `[const]` trait bounds
295+
.object = trait objects cannot have `[const]` trait bounds
296+
.item = this item cannot have `[const]` trait bounds
297+
298+
ast_passes_trait_fn_const =
299+
functions in {$in_impl ->
300+
[true] trait impls
301+
*[false] traits
302+
} cannot be declared const
303+
.label = functions in {$in_impl ->
304+
[true] trait impls
305+
*[false] traits
306+
} cannot be const
307+
.const_context_label = this declares all associated functions implicitly const
308+
.remove_const_sugg = remove the `const`{$requires_multiple_changes ->
309+
[true] {" ..."}
310+
*[false] {""}
311+
}
312+
.make_impl_const_sugg = ... and declare the impl to be const instead
313+
.make_trait_const_sugg = ... and declare the trait to be const instead
314+
315+
ast_passes_trait_object_single_bound = only a single explicit lifetime bound is permitted
316+
317+
ast_passes_ty_alias_without_body =
318+
free type alias without body
319+
.suggestion = provide a definition for the type
320+
321+
ast_passes_unsafe_item = {$kind} cannot be declared unsafe
322+
323+
ast_passes_unsafe_negative_impl = negative impls cannot be unsafe
324+
.negative = negative because of this
325+
.unsafe = unsafe because of this
326+
327+
ast_passes_unsafe_static =
328+
static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
329+
330+
ast_passes_visibility_not_permitted =
331+
visibility qualifiers are not permitted here
332+
.enum_variant = enum variants and their fields always share the visibility of the enum they are in
333+
.trait_impl = trait items always share the visibility of their trait
334+
.individual_impl_items = place qualifiers on individual impl items instead
335+
.individual_foreign_items = place qualifiers on individual foreign items instead
336+
.remove_qualifier_sugg = remove the qualifier
337+
338+
ast_passes_where_clause_after_type_alias = where clauses are not allowed after the type for type aliases
339+
.note = see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
340+
.help = add `#![feature(lazy_type_alias)]` to the crate attributes to enable
341+
342+
ast_passes_where_clause_before_type_alias = where clauses are not allowed before the type for type aliases
343+
.note = see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
344+
.remove_suggestion = remove this `where`
345+
.move_suggestion = move it to the end of the type declaration

compiler/rustc_ast_passes/src/errors.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,16 @@ pub(crate) struct IncompatibleFeatures {
950950
pub f2: Symbol,
951951
}
952952

953+
#[derive(Diagnostic)]
954+
#[diag("`{$parent}` requires {$missing} to be enabled")]
955+
#[help("enable all of these features")]
956+
pub(crate) struct MissingDependentFeatures {
957+
#[primary_span]
958+
pub parent_span: Span,
959+
pub parent: Symbol,
960+
pub missing: String,
961+
}
962+
953963
#[derive(Diagnostic)]
954964
#[diag("negative bounds are not supported")]
955965
pub(crate) struct NegativeBoundUnsupported {

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
441441
pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
442442
maybe_stage_features(sess, features, krate);
443443
check_incompatible_features(sess, features);
444+
check_dependent_features(sess, features);
444445
check_new_solver_banned_features(sess, features);
445446

446447
let mut visitor = PostExpansionVisitor { sess, features };
@@ -649,6 +650,27 @@ fn check_incompatible_features(sess: &Session, features: &Features) {
649650
}
650651
}
651652

653+
fn check_dependent_features(sess: &Session, features: &Features) {
654+
for &(parent, children) in
655+
rustc_feature::DEPENDENT_FEATURES.iter().filter(|(parent, _)| features.enabled(*parent))
656+
{
657+
if children.iter().any(|f| !features.enabled(*f)) {
658+
let parent_span = features
659+
.enabled_features_iter_stable_order()
660+
.find_map(|(name, span)| (name == parent).then_some(span))
661+
.unwrap();
662+
// FIXME: should probably format this in fluent instead of here
663+
let missing = children
664+
.iter()
665+
.filter(|f| !features.enabled(**f))
666+
.map(|s| format!("`{}`", s.as_str()))
667+
.intersperse(String::from(", "))
668+
.collect();
669+
sess.dcx().emit_err(errors::MissingDependentFeatures { parent_span, parent, missing });
670+
}
671+
}
672+
}
673+
652674
fn check_new_solver_banned_features(sess: &Session, features: &Features) {
653675
if !sess.opts.unstable_opts.next_solver.globally {
654676
return;

0 commit comments

Comments
 (0)