Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2521,16 +2521,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ExprKind::Block(block, _) => {
if let [stmt] = block.stmts.as_slice()
&& let StmtKind::Expr(expr) = &stmt.kind
&& matches!(
expr.kind,
ExprKind::Block(..)
| ExprKind::Path(..)
| ExprKind::Struct(..)
| ExprKind::Call(..)
| ExprKind::Tup(..)
| ExprKind::Array(..)
| ExprKind::ConstBlock(..)
)
{
return self.lower_expr_to_const_arg_direct(expr);
}
Expand All @@ -2553,6 +2543,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let span = expr.span;
let literal = self.lower_lit(literal, span);

if !matches!(literal.node, LitKind::Int(..)) {
let err =
self.dcx().struct_span_err(expr.span, "negated literal must be an integer");

return ConstArg {
hir_id: self.next_id(),
kind: hir::ConstArgKind::Error(err.emit()),
span,
};
}

ConstArg {
hir_id: self.lower_node_id(expr.id),
kind: hir::ConstArgKind::Literal { lit: literal.node, negated: true },
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1628,8 +1628,7 @@ impl<'a> Parser<'a> {
let first_expr = self.parse_expr()?;
if self.eat(exp!(Semi)) {
// Repeating array syntax: `[ 0; 512 ]`
let count =
self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?;
let count = self.parse_expr_anon_const(|_, _| MgcaDisambiguation::Direct)?;
self.expect(close)?;
ExprKind::Repeat(first_expr, count)
} else if self.eat(exp!(Comma)) {
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1587,9 +1587,7 @@ impl<'a> Parser<'a> {

let rhs = match (self.eat(exp!(Eq)), const_arg) {
(true, true) => ConstItemRhsKind::TypeConst {
rhs: Some(
self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?,
),
rhs: Some(self.parse_expr_anon_const(|_, _| MgcaDisambiguation::Direct)?),
},
(true, false) => ConstItemRhsKind::Body { rhs: Some(self.parse_expr()?) },
(false, true) => ConstItemRhsKind::TypeConst { rhs: None },
Expand Down
23 changes: 1 addition & 22 deletions compiler/rustc_parse/src/parser/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -915,28 +915,7 @@ impl<'a> Parser<'a> {
});
}

let mgca_disambiguation = self.mgca_direct_lit_hack(&expr);
Ok((expr, mgca_disambiguation))
}

/// Under `min_generic_const_args` we still allow *some* anon consts to be written without
/// a `const` block as it makes things quite a lot nicer. This function is useful for contexts
/// where we would like to use `MgcaDisambiguation::Direct` but need to fudge it to be `AnonConst`
/// in the presence of literals.
//
/// FIXME(min_generic_const_args): In the long term it would be nice to have a way to directly
/// represent literals in `hir::ConstArgKind` so that we can remove this special case by not
/// needing an anon const.
pub fn mgca_direct_lit_hack(&self, expr: &Expr) -> MgcaDisambiguation {
match &expr.kind {
ast::ExprKind::Lit(_) => MgcaDisambiguation::AnonConst,
ast::ExprKind::Unary(ast::UnOp::Neg, expr)
if matches!(expr.kind, ast::ExprKind::Lit(_)) =>
{
MgcaDisambiguation::AnonConst
}
_ => MgcaDisambiguation::Direct,
}
Ok((expr, MgcaDisambiguation::Direct))
}

/// Parse a generic argument in a path segment.
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_parse/src/parser/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -658,8 +658,7 @@ impl<'a> Parser<'a> {
};

let ty = if self.eat(exp!(Semi)) {
let mut length =
self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?;
let mut length = self.parse_expr_anon_const(|_, _| MgcaDisambiguation::Direct)?;

if let Err(e) = self.expect(exp!(CloseBracket)) {
// Try to recover from `X<Y, ...>` when `X::<Y, ...>` works
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,14 @@
error[E0277]: the trait bound `FreshTy(0): A` is not satisfied
error: type annotations needed for the literal
--> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:32:33
|
LL | let _: dyn A<Ty = i32, CT = 0>;
| ^ the trait `A` is not implemented for `FreshTy(0)`
|
help: the trait `A` is implemented for `()`
--> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:20:1
|
LL | impl A for () {
| ^^^^^^^^^^^^^
| ^

error[E0277]: the trait bound `FreshTy(0): A` is not satisfied
error: type annotations needed for the literal
--> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:34:34
|
LL | let _: &dyn A<Ty = i32, CT = 0> = &();
| ^ the trait `A` is not implemented for `FreshTy(0)`
|
help: the trait `A` is implemented for `()`
--> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:20:1
|
LL | impl A for () {
| ^^^^^^^^^^^^^
| ^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.
8 changes: 4 additions & 4 deletions tests/ui/const-generics/mgca/array-expr-complex.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ LL | takes_array::<{ [1, 2, 1 + 2] }>();
| ^^^^^

error: complex const arguments must be placed inside of a `const` block
--> $DIR/array-expr-complex.rs:10:19
--> $DIR/array-expr-complex.rs:10:21
|
LL | takes_array::<{ [X; 3] }>();
| ^^^^^^^^^^
| ^^^^^^

error: complex const arguments must be placed inside of a `const` block
--> $DIR/array-expr-complex.rs:12:19
--> $DIR/array-expr-complex.rs:12:21
|
LL | takes_array::<{ [0; Y] }>();
| ^^^^^^^^^^
| ^^^^^^

error: aborting due to 3 previous errors

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ where

fn bar<T>()
where
T: Trait2<3>, //~ ERROR: mismatched types
T: Trait2<3>, //~ ERROR: type annotations needed for the literal
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ error: expected `usize`, found const array
LL | T: Trait1<{ [] }>,
| ^^

error[E0308]: mismatched types
error: type annotations needed for the literal
--> $DIR/array-expr-type-mismatch-in-where-bound.rs:17:15
|
LL | T: Trait2<3>,
| ^ expected `[u8; 3]`, found integer
| ^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0308`.
16 changes: 8 additions & 8 deletions tests/ui/const-generics/mgca/explicit_anon_consts.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error: complex const arguments must be placed inside of a `const` block
--> $DIR/explicit_anon_consts.rs:13:33
--> $DIR/explicit_anon_consts.rs:13:35
|
LL | type Adt4<const N: usize> = Foo<{ 1 + 1 }>;
| ^^^^^^^^^
| ^^^^^

error: complex const arguments must be placed inside of a `const` block
--> $DIR/explicit_anon_consts.rs:21:34
Expand All @@ -17,22 +17,22 @@ LL | let _4 = [(); 1 + 1];
| ^^^^^

error: complex const arguments must be placed inside of a `const` block
--> $DIR/explicit_anon_consts.rs:45:43
--> $DIR/explicit_anon_consts.rs:45:45
|
LL | type const ITEM4<const N: usize>: usize = { 1 + 1 };
| ^^^^^^^^^
| ^^^^^

error: complex const arguments must be placed inside of a `const` block
--> $DIR/explicit_anon_consts.rs:62:23
--> $DIR/explicit_anon_consts.rs:62:25
|
LL | T4: Trait<ASSOC = { 1 + 1 }>,
| ^^^^^^^^^
| ^^^^^

error: complex const arguments must be placed inside of a `const` block
--> $DIR/explicit_anon_consts.rs:71:50
--> $DIR/explicit_anon_consts.rs:71:52
|
LL | struct Default4<const N: usize, const M: usize = { 1 + 1 }>;
| ^^^^^^^^^
| ^^^^^

error: generic parameters may not be used in const operations
--> $DIR/explicit_anon_consts.rs:42:51
Expand Down
17 changes: 11 additions & 6 deletions tests/ui/const-generics/mgca/nonsensical-negated-literal.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(adt_const_params, min_generic_const_args)]
#![feature(adt_const_params, min_generic_const_args, unsized_const_params)]
#![expect(incomplete_features)]

use std::marker::ConstParamTy;
Expand All @@ -10,17 +10,22 @@ struct Foo {

fn foo<const F: Foo>() {}

fn bar<const B: &'static str>() {}

fn main() {
foo::<{ Foo { field: -1_usize } }>();
//~^ ERROR: type annotations needed for the literal
foo::<{ Foo { field: { -1_usize } } }>();
//~^ ERROR: complex const arguments must be placed inside of a `const` block
//~^ ERROR: type annotations needed for the literal
foo::<{ Foo { field: -true } }>();
//~^ ERROR: the constant `true` is not of type `isize`
//~^ ERROR negated literal must be an integer
foo::<{ Foo { field: { -true } } }>();
//~^ ERROR: complex const arguments must be placed inside of a `const` block
//~^ ERROR negated literal must be an integer
foo::<{ Foo { field: -"<3" } }>();
//~^ ERROR: the constant `"<3"` is not of type `isize`
//~^ ERROR negated literal must be an integer
foo::<{ Foo { field: { -"<3" } } }>();
//~^ ERROR: complex const arguments must be placed inside of a `const` block
//~^ ERROR negated literal must be an integer

bar::<{ -"hi" }>();
//~^ ERROR: negated literal must be an integer
}
48 changes: 27 additions & 21 deletions tests/ui/const-generics/mgca/nonsensical-negated-literal.stderr
Original file line number Diff line number Diff line change
@@ -1,38 +1,44 @@
error: complex const arguments must be placed inside of a `const` block
--> $DIR/nonsensical-negated-literal.rs:16:26
error: negated literal must be an integer
--> $DIR/nonsensical-negated-literal.rs:20:26
|
LL | foo::<{ Foo { field: { -1_usize } } }>();
| ^^^^^^^^^^^^
LL | foo::<{ Foo { field: -true } }>();
| ^^^^^

error: complex const arguments must be placed inside of a `const` block
--> $DIR/nonsensical-negated-literal.rs:20:26
error: negated literal must be an integer
--> $DIR/nonsensical-negated-literal.rs:22:28
|
LL | foo::<{ Foo { field: { -true } } }>();
| ^^^^^^^^^
| ^^^^^

error: complex const arguments must be placed inside of a `const` block
error: negated literal must be an integer
--> $DIR/nonsensical-negated-literal.rs:24:26
|
LL | foo::<{ Foo { field: -"<3" } }>();
| ^^^^^

error: negated literal must be an integer
--> $DIR/nonsensical-negated-literal.rs:26:28
|
LL | foo::<{ Foo { field: { -"<3" } } }>();
| ^^^^^^^^^
| ^^^^^

error: negated literal must be an integer
--> $DIR/nonsensical-negated-literal.rs:29:13
|
LL | bar::<{ -"hi" }>();
| ^^^^^

error: type annotations needed for the literal
--> $DIR/nonsensical-negated-literal.rs:14:26
--> $DIR/nonsensical-negated-literal.rs:16:26
|
LL | foo::<{ Foo { field: -1_usize } }>();
| ^^^^^^^^

error: the constant `true` is not of type `isize`
--> $DIR/nonsensical-negated-literal.rs:18:13
|
LL | foo::<{ Foo { field: -true } }>();
| ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `bool`

error: the constant `"<3"` is not of type `isize`
--> $DIR/nonsensical-negated-literal.rs:22:13
error: type annotations needed for the literal
--> $DIR/nonsensical-negated-literal.rs:18:28
|
LL | foo::<{ Foo { field: -"<3" } }>();
| ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `&'static str`
LL | foo::<{ Foo { field: { -1_usize } } }>();
| ^^^^^^^^

error: aborting due to 6 previous errors
error: aborting due to 7 previous errors

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ struct A;
impl A {
type const B = 4;
//~^ ERROR: missing type for `const` item
//~| ERROR: type annotations needed for the literal
}

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,11 @@ help: provide a type for the item
LL | type const B: <type> = 4;
| ++++++++

error: aborting due to 1 previous error
error: type annotations needed for the literal
--> $DIR/type_const-inherent-const-omitted-type.rs:7:20
|
LL | type const B = 4;
| ^

error: aborting due to 2 previous errors

3 changes: 1 addition & 2 deletions tests/ui/const-generics/mgca/type_const-mismatched-types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

type const FREE: u32 = 5_usize;
//~^ ERROR the constant `5` is not of type `u32`
//~| ERROR mismatched types

type const FREE2: isize = FREE;
//~^ ERROR the constant `5` is not of type `isize`
Expand All @@ -14,7 +13,7 @@ trait Tr {

impl Tr for () {
type const N: usize = false;
//~^ ERROR mismatched types
//~^ ERROR the constant `false` is not of type `usize`
}

fn main() {}
23 changes: 5 additions & 18 deletions tests/ui/const-generics/mgca/type_const-mismatched-types.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,16 @@ LL | type const FREE: u32 = 5_usize;
| ^^^^^^^^^^^^^^^^^^^^ expected `u32`, found `usize`

error: the constant `5` is not of type `isize`
--> $DIR/type_const-mismatched-types.rs:8:1
--> $DIR/type_const-mismatched-types.rs:7:1
|
LL | type const FREE2: isize = FREE;
| ^^^^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `usize`

error[E0308]: mismatched types
--> $DIR/type_const-mismatched-types.rs:16:27
error: the constant `false` is not of type `usize`
--> $DIR/type_const-mismatched-types.rs:15:5
|
LL | type const N: usize = false;
| ^^^^^ expected `usize`, found `bool`
| ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool`

error[E0308]: mismatched types
--> $DIR/type_const-mismatched-types.rs:4:24
|
LL | type const FREE: u32 = 5_usize;
| ^^^^^^^ expected `u32`, found `usize`
|
help: change the type of the numeric literal from `usize` to `u32`
|
LL - type const FREE: u32 = 5_usize;
LL + type const FREE: u32 = 5_u32;
|

error: aborting due to 4 previous errors
error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0308`.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ struct GoodS;
impl BadTr for GoodS {
type const NUM: = 84;
//~^ ERROR: missing type for `const` item
//~| ERROR: type annotations needed for the literal

}

Expand Down
Loading
Loading