1
Fork 0

Rollup merge of #104614 - Nilstrieb:type-ascribe!, r=TaKO8Ki

Add `type_ascribe!` macro as placeholder syntax for type ascription

This makes it still possible to test the internal semantics of type ascription even once the `:`-syntax is removed from the parser. The macro now gets used in a bunch of UI tests that test the semantics and not syntax of type ascription.

I might have forgotten a few tests but this should hopefully be most of them. The remaining ones will certainly be found once type ascription is removed from the parser altogether.

Part of #101728
This commit is contained in:
Matthias Krüger 2022-12-02 08:28:08 +01:00 committed by GitHub
commit 4fdc3eb176
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 262 additions and 221 deletions

View file

@ -45,6 +45,7 @@ mod log_syntax;
mod source_util; mod source_util;
mod test; mod test;
mod trace_macros; mod trace_macros;
mod type_ascribe;
mod util; mod util;
pub mod asm; pub mod asm;
@ -92,6 +93,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
unreachable: edition_panic::expand_unreachable, unreachable: edition_panic::expand_unreachable,
stringify: source_util::expand_stringify, stringify: source_util::expand_stringify,
trace_macros: trace_macros::expand_trace_macros, trace_macros: trace_macros::expand_trace_macros,
type_ascribe: type_ascribe::expand_type_ascribe,
} }
register_attr! { register_attr! {

View file

@ -0,0 +1,35 @@
use rustc_ast::ptr::P;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::{token, Expr, ExprKind, Ty};
use rustc_errors::PResult;
use rustc_expand::base::{self, DummyResult, ExtCtxt, MacEager};
use rustc_span::Span;
pub fn expand_type_ascribe(
cx: &mut ExtCtxt<'_>,
span: Span,
tts: TokenStream,
) -> Box<dyn base::MacResult + 'static> {
let (expr, ty) = match parse_ascribe(cx, tts) {
Ok(parsed) => parsed,
Err(mut err) => {
err.emit();
return DummyResult::any(span);
}
};
let asc_expr = cx.expr(span, ExprKind::Type(expr, ty));
return MacEager::expr(asc_expr);
}
fn parse_ascribe<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P<Expr>, P<Ty>)> {
let mut parser = cx.new_parser_from_tts(stream);
let expr = parser.parse_expr()?;
parser.expect(&token::Comma)?;
let ty = parser.parse_ty()?;
Ok((expr, ty))
}

View file

@ -1488,6 +1488,7 @@ symbols! {
ty, ty,
type_alias_enum_variants, type_alias_enum_variants,
type_alias_impl_trait, type_alias_impl_trait,
type_ascribe,
type_ascription, type_ascription,
type_changing_struct_update, type_changing_struct_update,
type_id, type_id,

View file

@ -1546,6 +1546,18 @@ pub(crate) mod builtin {
/* compiler built-in */ /* compiler built-in */
} }
/// Unstable placeholder for type ascription.
#[rustc_builtin_macro]
#[unstable(
feature = "type_ascription",
issue = "23416",
reason = "placeholder syntax for type ascription"
)]
#[cfg(not(bootstrap))]
pub macro type_ascribe($expr:expr, $ty:ty) {
/* compiler built-in */
}
/// Unstable implementation detail of the `rustc` compiler, do not use. /// Unstable implementation detail of the `rustc` compiler, do not use.
#[rustc_builtin_macro] #[rustc_builtin_macro]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]

View file

@ -98,3 +98,11 @@ pub use crate::macros::builtin::cfg_accessible;
reason = "`cfg_eval` is a recently implemented feature" reason = "`cfg_eval` is a recently implemented feature"
)] )]
pub use crate::macros::builtin::cfg_eval; pub use crate::macros::builtin::cfg_eval;
#[unstable(
feature = "type_ascription",
issue = "23416",
reason = "placeholder syntax for type ascription"
)]
#[cfg(not(bootstrap))]
pub use crate::macros::builtin::type_ascribe;

View file

@ -85,6 +85,15 @@ pub use core::prelude::v1::cfg_accessible;
)] )]
pub use core::prelude::v1::cfg_eval; pub use core::prelude::v1::cfg_eval;
// Do not `doc(no_inline)` either.
#[unstable(
feature = "type_ascription",
issue = "23416",
reason = "placeholder syntax for type ascription"
)]
#[cfg(not(bootstrap))]
pub use core::prelude::v1::type_ascribe;
// The file so far is equivalent to src/libcore/prelude/v1.rs, // The file so far is equivalent to src/libcore/prelude/v1.rs,
// and below to src/liballoc/prelude.rs. // and below to src/liballoc/prelude.rs.
// Those files are duplicated rather than using glob imports // Those files are duplicated rather than using glob imports

View file

@ -1,9 +1,11 @@
#![feature(type_ascription)]
fn e() { fn e() {
p:a<p:p<e=6>> type_ascribe!(p, a<p:p<e=6>>);
//~^ ERROR comparison operators //~^ ERROR cannot find type `a` in this scope
//~| ERROR cannot find value //~| ERROR cannot find value
//~| ERROR associated const equality //~| ERROR associated const equality
//~| ERROR associated const equality //~| ERROR cannot find trait `p` in this scope
//~| ERROR associated type bounds //~| ERROR associated type bounds
} }

View file

@ -1,65 +1,40 @@
error: comparison operators cannot be chained
--> $DIR/issue-93835.rs:2:8
|
LL | fn e() {
| - while parsing this struct
LL | p:a<p:p<e=6>>
| ^ ^
|
= help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
= help: or use `(...)` if you meant to specify fn arguments
error[E0425]: cannot find value `p` in this scope error[E0425]: cannot find value `p` in this scope
--> $DIR/issue-93835.rs:2:5 --> $DIR/issue-93835.rs:4:19
| |
LL | p:a<p:p<e=6>> LL | type_ascribe!(p, a<p:p<e=6>>);
| ^ not found in this scope | ^ not found in this scope
error[E0412]: cannot find type `a` in this scope
--> $DIR/issue-93835.rs:4:22
| |
help: you might have meant to write a `struct` literal LL | type_ascribe!(p, a<p:p<e=6>>);
| ^ not found in this scope
error[E0405]: cannot find trait `p` in this scope
--> $DIR/issue-93835.rs:4:26
| |
LL ~ fn e() { SomeStruct { LL | type_ascribe!(p, a<p:p<e=6>>);
LL | p:a<p:p<e=6>> | ^ not found in this scope
...
LL |
LL ~ }}
|
help: maybe you meant to write a path separator here
|
LL | p::a<p:p<e=6>>
| ~~
help: maybe you meant to write an assignment here
|
LL | let p:a<p:p<e=6>>
| ~~~~~
error[E0658]: associated const equality is incomplete error[E0658]: associated const equality is incomplete
--> $DIR/issue-93835.rs:2:13 --> $DIR/issue-93835.rs:4:28
| |
LL | p:a<p:p<e=6>> LL | type_ascribe!(p, a<p:p<e=6>>);
| ^^^ | ^^^
|
= note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
= help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
error[E0658]: associated const equality is incomplete
--> $DIR/issue-93835.rs:2:13
|
LL | p:a<p:p<e=6>>
| ^^^
| |
= note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
= help: add `#![feature(associated_const_equality)]` to the crate attributes to enable = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
error[E0658]: associated type bounds are unstable error[E0658]: associated type bounds are unstable
--> $DIR/issue-93835.rs:2:9 --> $DIR/issue-93835.rs:4:24
| |
LL | p:a<p:p<e=6>> LL | type_ascribe!(p, a<p:p<e=6>>);
| ^^^^^^^^ | ^^^^^^^^
| |
= note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
error: aborting due to 5 previous errors error: aborting due to 5 previous errors
Some errors have detailed explanations: E0425, E0658. Some errors have detailed explanations: E0405, E0412, E0425, E0658.
For more information about an error, try `rustc --explain E0425`. For more information about an error, try `rustc --explain E0405`.

View file

@ -1,5 +1,7 @@
#![feature(type_ascription)]
fn main() { fn main() {
2: n([u8; || 1]) type_ascribe!(2, n([u8; || 1]))
//~^ ERROR cannot find type `n` in this scope //~^ ERROR cannot find type `n` in this scope
//~| ERROR mismatched types //~| ERROR mismatched types
} }

View file

@ -1,21 +1,26 @@
error[E0412]: cannot find type `n` in this scope error[E0412]: cannot find type `n` in this scope
--> $DIR/issue-90871.rs:2:8 --> $DIR/issue-90871.rs:4:22
| |
LL | 2: n([u8; || 1]) LL | type_ascribe!(2, n([u8; || 1]))
| ^ expecting a type here because of type ascription | ^ help: a trait with a similar name exists: `Fn`
|
::: $SRC_DIR/core/src/ops/function.rs:LL:COL
|
LL | pub trait Fn<Args: Tuple>: FnMut<Args> {
| -------------------------------------- similarly named trait `Fn` defined here
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-90871.rs:2:15 --> $DIR/issue-90871.rs:4:29
| |
LL | 2: n([u8; || 1]) LL | type_ascribe!(2, n([u8; || 1]))
| ^^^^ expected `usize`, found closure | ^^^^ expected `usize`, found closure
| |
= note: expected type `usize` = note: expected type `usize`
found closure `[closure@$DIR/issue-90871.rs:2:15: 2:17]` found closure `[closure@$DIR/issue-90871.rs:4:29: 4:31]`
help: use parentheses to call this closure help: use parentheses to call this closure
| |
LL | 2: n([u8; (|| 1)()]) LL | type_ascribe!(2, n([u8; (|| 1)()]))
| + +++ | + +++
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -6,27 +6,27 @@
use std::fmt::Debug; use std::fmt::Debug;
pub fn main() { pub fn main() {
let _ = box { [1, 2, 3] }: Box<[i32]>; //~ ERROR mismatched types let _ = type_ascribe!(box { [1, 2, 3] }, Box<[i32]>); //~ ERROR mismatched types
let _ = box if true { [1, 2, 3] } else { [1, 3, 4] }: Box<[i32]>; //~ ERROR mismatched types let _ = type_ascribe!(box if true { [1, 2, 3] } else { [1, 3, 4] }, Box<[i32]>); //~ ERROR mismatched types
let _ = box match true { true => [1, 2, 3], false => [1, 3, 4] }: Box<[i32]>; let _ = type_ascribe!(box match true { true => [1, 2, 3], false => [1, 3, 4] }, Box<[i32]>);
//~^ ERROR mismatched types //~^ ERROR mismatched types
let _ = box { |x| (x as u8) }: Box<dyn Fn(i32) -> _>; //~ ERROR mismatched types let _ = type_ascribe!(box { |x| (x as u8) }, Box<dyn Fn(i32) -> _>); //~ ERROR mismatched types
let _ = box if true { false } else { true }: Box<dyn Debug>; //~ ERROR mismatched types let _ = type_ascribe!(box if true { false } else { true }, Box<dyn Debug>); //~ ERROR mismatched types
let _ = box match true { true => 'a', false => 'b' }: Box<dyn Debug>; //~ ERROR mismatched types let _ = type_ascribe!(box match true { true => 'a', false => 'b' }, Box<dyn Debug>); //~ ERROR mismatched types
let _ = &{ [1, 2, 3] }: &[i32]; //~ ERROR mismatched types let _ = type_ascribe!(&{ [1, 2, 3] }, &[i32]); //~ ERROR mismatched types
let _ = &if true { [1, 2, 3] } else { [1, 3, 4] }: &[i32]; //~ ERROR mismatched types let _ = type_ascribe!(&if true { [1, 2, 3] } else { [1, 3, 4] }, &[i32]); //~ ERROR mismatched types
let _ = &match true { true => [1, 2, 3], false => [1, 3, 4] }: &[i32]; let _ = type_ascribe!(&match true { true => [1, 2, 3], false => [1, 3, 4] }, &[i32]);
//~^ ERROR mismatched types //~^ ERROR mismatched types
let _ = &{ |x| (x as u8) }: &dyn Fn(i32) -> _; //~ ERROR mismatched types let _ = type_ascribe!(&{ |x| (x as u8) }, &dyn Fn(i32) -> _); //~ ERROR mismatched types
let _ = &if true { false } else { true }: &dyn Debug; //~ ERROR mismatched types let _ = type_ascribe!(&if true { false } else { true }, &dyn Debug); //~ ERROR mismatched types
let _ = &match true { true => 'a', false => 'b' }: &dyn Debug; //~ ERROR mismatched types let _ = type_ascribe!(&match true { true => 'a', false => 'b' }, &dyn Debug); //~ ERROR mismatched types
let _ = Box::new([1, 2, 3]): Box<[i32]>; //~ ERROR mismatched types let _ = type_ascribe!(Box::new([1, 2, 3]), Box<[i32]>); //~ ERROR mismatched types
let _ = Box::new(|x| (x as u8)): Box<dyn Fn(i32) -> _>; //~ ERROR mismatched types let _ = type_ascribe!(Box::new(|x| (x as u8)), Box<dyn Fn(i32) -> _>); //~ ERROR mismatched types
let _ = vec![ let _ = type_ascribe!(vec![
Box::new(|x| (x as u8)), Box::new(|x| (x as u8)),
box |x| (x as i16 as u8), box |x| (x as i16 as u8),
]: Vec<Box<dyn Fn(i32) -> _>>; ], Vec<Box<dyn Fn(i32) -> _>>);
} }

View file

@ -1,128 +1,128 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/coerce-expect-unsized-ascribed.rs:9:13 --> $DIR/coerce-expect-unsized-ascribed.rs:9:27
| |
LL | let _ = box { [1, 2, 3] }: Box<[i32]>; LL | let _ = type_ascribe!(box { [1, 2, 3] }, Box<[i32]>);
| ^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]` | ^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
| |
= note: expected struct `Box<[i32]>` = note: expected struct `Box<[i32]>`
found struct `Box<[i32; 3]>` found struct `Box<[i32; 3]>`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/coerce-expect-unsized-ascribed.rs:10:13 --> $DIR/coerce-expect-unsized-ascribed.rs:10:27
| |
LL | let _ = box if true { [1, 2, 3] } else { [1, 3, 4] }: Box<[i32]>; LL | let _ = type_ascribe!(box if true { [1, 2, 3] } else { [1, 3, 4] }, Box<[i32]>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
| |
= note: expected struct `Box<[i32]>` = note: expected struct `Box<[i32]>`
found struct `Box<[i32; 3]>` found struct `Box<[i32; 3]>`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/coerce-expect-unsized-ascribed.rs:11:13 --> $DIR/coerce-expect-unsized-ascribed.rs:11:27
| |
LL | let _ = box match true { true => [1, 2, 3], false => [1, 3, 4] }: Box<[i32]>; LL | let _ = type_ascribe!(box match true { true => [1, 2, 3], false => [1, 3, 4] }, Box<[i32]>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
| |
= note: expected struct `Box<[i32]>` = note: expected struct `Box<[i32]>`
found struct `Box<[i32; 3]>` found struct `Box<[i32; 3]>`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/coerce-expect-unsized-ascribed.rs:13:13 --> $DIR/coerce-expect-unsized-ascribed.rs:13:27
| |
LL | let _ = box { |x| (x as u8) }: Box<dyn Fn(i32) -> _>; LL | let _ = type_ascribe!(box { |x| (x as u8) }, Box<dyn Fn(i32) -> _>);
| ^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Fn`, found closure | ^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Fn`, found closure
| |
= note: expected struct `Box<dyn Fn(i32) -> u8>` = note: expected struct `Box<dyn Fn(i32) -> u8>`
found struct `Box<[closure@$DIR/coerce-expect-unsized-ascribed.rs:13:19: 13:22]>` found struct `Box<[closure@$DIR/coerce-expect-unsized-ascribed.rs:13:33: 13:36]>`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/coerce-expect-unsized-ascribed.rs:14:13 --> $DIR/coerce-expect-unsized-ascribed.rs:14:27
| |
LL | let _ = box if true { false } else { true }: Box<dyn Debug>; LL | let _ = type_ascribe!(box if true { false } else { true }, Box<dyn Debug>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `bool` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `bool`
| |
= note: expected struct `Box<dyn Debug>` = note: expected struct `Box<dyn Debug>`
found struct `Box<bool>` found struct `Box<bool>`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/coerce-expect-unsized-ascribed.rs:15:13 --> $DIR/coerce-expect-unsized-ascribed.rs:15:27
| |
LL | let _ = box match true { true => 'a', false => 'b' }: Box<dyn Debug>; LL | let _ = type_ascribe!(box match true { true => 'a', false => 'b' }, Box<dyn Debug>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `char` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `char`
| |
= note: expected struct `Box<dyn Debug>` = note: expected struct `Box<dyn Debug>`
found struct `Box<char>` found struct `Box<char>`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/coerce-expect-unsized-ascribed.rs:17:13 --> $DIR/coerce-expect-unsized-ascribed.rs:17:27
| |
LL | let _ = &{ [1, 2, 3] }: &[i32]; LL | let _ = type_ascribe!(&{ [1, 2, 3] }, &[i32]);
| ^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]` | ^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
| |
= note: expected reference `&[i32]` = note: expected reference `&[i32]`
found reference `&[i32; 3]` found reference `&[i32; 3]`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/coerce-expect-unsized-ascribed.rs:18:13 --> $DIR/coerce-expect-unsized-ascribed.rs:18:27
| |
LL | let _ = &if true { [1, 2, 3] } else { [1, 3, 4] }: &[i32]; LL | let _ = type_ascribe!(&if true { [1, 2, 3] } else { [1, 3, 4] }, &[i32]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
| |
= note: expected reference `&[i32]` = note: expected reference `&[i32]`
found reference `&[i32; 3]` found reference `&[i32; 3]`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/coerce-expect-unsized-ascribed.rs:19:13 --> $DIR/coerce-expect-unsized-ascribed.rs:19:27
| |
LL | let _ = &match true { true => [1, 2, 3], false => [1, 3, 4] }: &[i32]; LL | let _ = type_ascribe!(&match true { true => [1, 2, 3], false => [1, 3, 4] }, &[i32]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
| |
= note: expected reference `&[i32]` = note: expected reference `&[i32]`
found reference `&[i32; 3]` found reference `&[i32; 3]`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/coerce-expect-unsized-ascribed.rs:21:13 --> $DIR/coerce-expect-unsized-ascribed.rs:21:27
| |
LL | let _ = &{ |x| (x as u8) }: &dyn Fn(i32) -> _; LL | let _ = type_ascribe!(&{ |x| (x as u8) }, &dyn Fn(i32) -> _);
| ^^^^^^^^^^^^^^^^^^ expected trait object `dyn Fn`, found closure | ^^^^^^^^^^^^^^^^^^ expected trait object `dyn Fn`, found closure
| |
= note: expected reference `&dyn Fn(i32) -> u8` = note: expected reference `&dyn Fn(i32) -> u8`
found reference `&[closure@$DIR/coerce-expect-unsized-ascribed.rs:21:16: 21:19]` found reference `&[closure@$DIR/coerce-expect-unsized-ascribed.rs:21:30: 21:33]`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/coerce-expect-unsized-ascribed.rs:22:13 --> $DIR/coerce-expect-unsized-ascribed.rs:22:27
| |
LL | let _ = &if true { false } else { true }: &dyn Debug; LL | let _ = type_ascribe!(&if true { false } else { true }, &dyn Debug);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `bool` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `bool`
| |
= note: expected reference `&dyn Debug` = note: expected reference `&dyn Debug`
found reference `&bool` found reference `&bool`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/coerce-expect-unsized-ascribed.rs:23:13 --> $DIR/coerce-expect-unsized-ascribed.rs:23:27
| |
LL | let _ = &match true { true => 'a', false => 'b' }: &dyn Debug; LL | let _ = type_ascribe!(&match true { true => 'a', false => 'b' }, &dyn Debug);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `char` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `char`
| |
= note: expected reference `&dyn Debug` = note: expected reference `&dyn Debug`
found reference `&char` found reference `&char`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/coerce-expect-unsized-ascribed.rs:25:13 --> $DIR/coerce-expect-unsized-ascribed.rs:25:27
| |
LL | let _ = Box::new([1, 2, 3]): Box<[i32]>; LL | let _ = type_ascribe!(Box::new([1, 2, 3]), Box<[i32]>);
| ^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]` | ^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
| |
= note: expected struct `Box<[i32]>` = note: expected struct `Box<[i32]>`
found struct `Box<[i32; 3]>` found struct `Box<[i32; 3]>`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/coerce-expect-unsized-ascribed.rs:26:13 --> $DIR/coerce-expect-unsized-ascribed.rs:26:27
| |
LL | let _ = Box::new(|x| (x as u8)): Box<dyn Fn(i32) -> _>; LL | let _ = type_ascribe!(Box::new(|x| (x as u8)), Box<dyn Fn(i32) -> _>);
| ^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Fn`, found closure | ^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Fn`, found closure
| |
= note: expected struct `Box<dyn Fn(i32) -> u8>` = note: expected struct `Box<dyn Fn(i32) -> u8>`
found struct `Box<[closure@$DIR/coerce-expect-unsized-ascribed.rs:26:22: 26:25]>` found struct `Box<[closure@$DIR/coerce-expect-unsized-ascribed.rs:26:36: 26:39]>`
error: aborting due to 14 previous errors error: aborting due to 14 previous errors

View file

@ -45,7 +45,7 @@ fn main() {
const TUPLE: (OND, OND) = (None, None); const TUPLE: (OND, OND) = (None, None);
match (None, None) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), }; match (None, None) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), };
const TYPE_ASCRIPTION: OND = None: OND; const TYPE_ASCRIPTION: OND = type_ascribe!(None, OND);
match None { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), }; match None { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), };
const ARRAY: [OND; 2] = [None, None]; const ARRAY: [OND; 2] = [None, None];

View file

@ -53,7 +53,7 @@ fn main() {
match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), }; match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), };
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
const TYPE_ASCRIPTION: OND = Some(NoDerive): OND; const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND);
match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), }; match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), };
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`

View file

@ -1,7 +1,7 @@
#![feature(type_ascription)] #![feature(type_ascription)]
enum Bug<S> { //~ ERROR parameter `S` is never used enum Bug<S> { //~ ERROR parameter `S` is never used
Var = 0: S, Var = type_ascribe!(0, S),
//~^ ERROR generic parameters may not be used //~^ ERROR generic parameters may not be used
} }

View file

@ -1,8 +1,8 @@
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/issue-67945-2.rs:4:14 --> $DIR/issue-67945-2.rs:4:28
| |
LL | Var = 0: S, LL | Var = type_ascribe!(0, S),
| ^ cannot perform const operation using `S` | ^ cannot perform const operation using `S`
| |
= note: type parameters may not be used in const expressions = note: type parameters may not be used in const expressions
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions

View file

@ -51,22 +51,13 @@ mod casts {
mod typeascription { mod typeascription {
fn outside() -> u8 { fn outside() -> u8 {
({ 0 }): u8 type_ascribe!(({ 0 }), u8)
}
fn inside() -> u8 {
({ 0 }: u8)
} }
fn outside_match() -> u8 { fn outside_match() -> u8 {
(match 0 { x => x }): u8 type_ascribe!((match 0 { x => x }), u8)
}
fn inside_match() -> u8 {
(match 0 { x => x }: u8)
} }
fn outside_if() -> u8 { fn outside_if() -> u8 {
(if false { 0 } else { 0 }): u8 type_ascribe!((if false { 0 } else { 0 }), u8)
}
fn inside_if() -> u8 {
(if false { 0 } else { 0 }: u8)
} }
} }

View file

@ -6,5 +6,5 @@
fn main() { fn main() {
let x = [1, 2, 3]; let x = [1, 2, 3];
// The RHS should coerce to &[i32] // The RHS should coerce to &[i32]
let _y : &[i32] = &x : &[i32; 3]; let _y : &[i32] = type_ascribe!(&x, &[i32; 3]);
} }

View file

@ -8,17 +8,17 @@ type PairCoupledTypes<T> = (T, T);
type PairCoupledRegions<'a, T> = (&'a T, &'a T); type PairCoupledRegions<'a, T> = (&'a T, &'a T);
fn uncoupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { fn uncoupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
let ((y, _z),) = ((s, _x),): (PairUncoupled<_>,); let ((y, _z),) = type_ascribe!(((s, _x),), (PairUncoupled<_>,));
y // OK y // OK
} }
fn coupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { fn coupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
let ((y, _z),) = ((s, _x),): (PairCoupledTypes<_>,); let ((y, _z),) = type_ascribe!(((s, _x),), (PairCoupledTypes<_>,));
y //~ ERROR lifetime may not live long enough y //~ ERROR lifetime may not live long enough
} }
fn coupled_regions_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { fn coupled_regions_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
let ((y, _z),) = ((s, _x),): (PairCoupledRegions<_>,); let ((y, _z),) = type_ascribe!(((s, _x),), (PairCoupledRegions<_>,));
y //~ ERROR lifetime may not live long enough y //~ ERROR lifetime may not live long enough
} }

View file

@ -3,7 +3,7 @@ error: lifetime may not live long enough
| |
LL | fn coupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { LL | fn coupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
| -- lifetime `'a` defined here | -- lifetime `'a` defined here
LL | let ((y, _z),) = ((s, _x),): (PairCoupledTypes<_>,); LL | let ((y, _z),) = type_ascribe!(((s, _x),), (PairCoupledTypes<_>,));
LL | y LL | y
| ^ returning this value requires that `'a` must outlive `'static` | ^ returning this value requires that `'a` must outlive `'static`
@ -12,7 +12,7 @@ error: lifetime may not live long enough
| |
LL | fn coupled_regions_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { LL | fn coupled_regions_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
| -- lifetime `'a` defined here | -- lifetime `'a` defined here
LL | let ((y, _z),) = ((s, _x),): (PairCoupledRegions<_>,); LL | let ((y, _z),) = type_ascribe!(((s, _x),), (PairCoupledRegions<_>,));
LL | y LL | y
| ^ returning this value requires that `'a` must outlive `'static` | ^ returning this value requires that `'a` must outlive `'static`

View file

@ -3,5 +3,5 @@
fn main() { fn main() {
let x = 22_u32; let x = 22_u32;
let y: &u32 = &x: &'static u32; //~ ERROR E0597 let y: &u32 = type_ascribe!(&x, &'static u32); //~ ERROR E0597
} }

View file

@ -1,10 +1,10 @@
error[E0597]: `x` does not live long enough error[E0597]: `x` does not live long enough
--> $DIR/type_ascription_static_lifetime.rs:6:19 --> $DIR/type_ascription_static_lifetime.rs:6:33
| |
LL | let y: &u32 = &x: &'static u32; LL | let y: &u32 = type_ascribe!(&x, &'static u32);
| ^^-------------- | --------------^^---------------
| | | | |
| borrowed value does not live long enough | | borrowed value does not live long enough
| type annotation requires that `x` is borrowed for `'static` | type annotation requires that `x` is borrowed for `'static`
LL | } LL | }
| - `x` dropped here while still borrowed | - `x` dropped here while still borrowed

View file

@ -18,7 +18,7 @@ fn main() {
let index_deref_ref = &raw const SLICE_REF[1]; let index_deref_ref = &raw const SLICE_REF[1];
let x = 0; let x = 0;
let ascribe_ref = &raw const (x: i32); let ascribe_ref = &raw const type_ascribe!(x, i32);
let ascribe_deref = &raw const (*ARRAY_REF: [i32; 2]); let ascribe_deref = &raw const type_ascribe!(*ARRAY_REF, [i32; 2]);
let ascribe_index_deref = &raw const (ARRAY_REF[0]: i32); let ascribe_index_deref = &raw const type_ascribe!(ARRAY_REF[0], i32);
} }

View file

@ -8,24 +8,24 @@ const PAIR: (i32, i64) = (1, 2);
const ARRAY: [i32; 2] = [1, 2]; const ARRAY: [i32; 2] = [1, 2];
fn main() { fn main() {
let ref_expr = &raw const 2; //~ ERROR cannot take address let ref_expr = &raw const 2; //~ ERROR cannot take address
let mut_ref_expr = &raw mut 3; //~ ERROR cannot take address let mut_ref_expr = &raw mut 3; //~ ERROR cannot take address
let ref_const = &raw const FOUR; //~ ERROR cannot take address let ref_const = &raw const FOUR; //~ ERROR cannot take address
let mut_ref_const = &raw mut FOUR; //~ ERROR cannot take address let mut_ref_const = &raw mut FOUR; //~ ERROR cannot take address
let field_ref_expr = &raw const (1, 2).0; //~ ERROR cannot take address let field_ref_expr = &raw const (1, 2).0; //~ ERROR cannot take address
let mut_field_ref_expr = &raw mut (1, 2).0; //~ ERROR cannot take address let mut_field_ref_expr = &raw mut (1, 2).0; //~ ERROR cannot take address
let field_ref = &raw const PAIR.0; //~ ERROR cannot take address let field_ref = &raw const PAIR.0; //~ ERROR cannot take address
let mut_field_ref = &raw mut PAIR.0; //~ ERROR cannot take address let mut_field_ref = &raw mut PAIR.0; //~ ERROR cannot take address
let index_ref_expr = &raw const [1, 2][0]; //~ ERROR cannot take address let index_ref_expr = &raw const [1, 2][0]; //~ ERROR cannot take address
let mut_index_ref_expr = &raw mut [1, 2][0]; //~ ERROR cannot take address let mut_index_ref_expr = &raw mut [1, 2][0]; //~ ERROR cannot take address
let index_ref = &raw const ARRAY[0]; //~ ERROR cannot take address let index_ref = &raw const ARRAY[0]; //~ ERROR cannot take address
let mut_index_ref = &raw mut ARRAY[1]; //~ ERROR cannot take address let mut_index_ref = &raw mut ARRAY[1]; //~ ERROR cannot take address
let ref_ascribe = &raw const (2: i32); //~ ERROR cannot take address let ref_ascribe = &raw const type_ascribe!(2, i32); //~ ERROR cannot take address
let mut_ref_ascribe = &raw mut (3: i32); //~ ERROR cannot take address let mut_ref_ascribe = &raw mut type_ascribe!(3, i32); //~ ERROR cannot take address
let ascribe_field_ref = &raw const (PAIR.0: i32); //~ ERROR cannot take address let ascribe_field_ref = &raw const type_ascribe!(PAIR.0, i32); //~ ERROR cannot take address
let ascribe_index_ref = &raw mut (ARRAY[0]: i32); //~ ERROR cannot take address let ascribe_index_ref = &raw mut type_ascribe!(ARRAY[0], i32); //~ ERROR cannot take address
} }

View file

@ -73,26 +73,26 @@ LL | let mut_index_ref = &raw mut ARRAY[1];
error[E0745]: cannot take address of a temporary error[E0745]: cannot take address of a temporary
--> $DIR/raw-ref-temp.rs:26:34 --> $DIR/raw-ref-temp.rs:26:34
| |
LL | let ref_ascribe = &raw const (2: i32); LL | let ref_ascribe = &raw const type_ascribe!(2, i32);
| ^^^^^^^^ temporary value | ^^^^^^^^^^^^^^^^^^^^^ temporary value
error[E0745]: cannot take address of a temporary error[E0745]: cannot take address of a temporary
--> $DIR/raw-ref-temp.rs:27:36 --> $DIR/raw-ref-temp.rs:27:36
| |
LL | let mut_ref_ascribe = &raw mut (3: i32); LL | let mut_ref_ascribe = &raw mut type_ascribe!(3, i32);
| ^^^^^^^^ temporary value | ^^^^^^^^^^^^^^^^^^^^^ temporary value
error[E0745]: cannot take address of a temporary error[E0745]: cannot take address of a temporary
--> $DIR/raw-ref-temp.rs:29:40 --> $DIR/raw-ref-temp.rs:29:40
| |
LL | let ascribe_field_ref = &raw const (PAIR.0: i32); LL | let ascribe_field_ref = &raw const type_ascribe!(PAIR.0, i32);
| ^^^^^^^^^^^^^ temporary value | ^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value
error[E0745]: cannot take address of a temporary error[E0745]: cannot take address of a temporary
--> $DIR/raw-ref-temp.rs:30:38 --> $DIR/raw-ref-temp.rs:30:38
| |
LL | let ascribe_index_ref = &raw mut (ARRAY[0]: i32); LL | let ascribe_index_ref = &raw mut type_ascribe!(ARRAY[0], i32);
| ^^^^^^^^^^^^^^^ temporary value | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value
error: aborting due to 16 previous errors error: aborting due to 16 previous errors

View file

@ -6,7 +6,7 @@
fn a() { fn a() {
// the cast is unreachable: // the cast is unreachable:
let x = {return}: !; //~ ERROR unreachable let x = type_ascribe!({return}, !); //~ ERROR unreachable
} }
fn main() { } fn main() { }

View file

@ -1,10 +1,10 @@
error: unreachable expression error: unreachable expression
--> $DIR/expr_type.rs:9:13 --> $DIR/expr_type.rs:9:13
| |
LL | let x = {return}: !; LL | let x = type_ascribe!({return}, !);
| ^------^^^^ | ^^^^^^^^^^^^^^^------^^^^^
| || | | |
| |any code following this expression is unreachable | | any code following this expression is unreachable
| unreachable expression | unreachable expression
| |
note: the lint level is defined here note: the lint level is defined here

View file

@ -4,10 +4,10 @@
fn main() { fn main() {
let arr = &[1u8, 2, 3]; let arr = &[1u8, 2, 3];
let ref x = arr: &[u8]; //~ ERROR mismatched types let ref x = type_ascribe!(arr, &[u8]); //~ ERROR mismatched types
let ref mut x = arr: &[u8]; //~ ERROR mismatched types let ref mut x = type_ascribe!(arr, &[u8]); //~ ERROR mismatched types
match arr: &[u8] { //~ ERROR mismatched types match type_ascribe!(arr, &[u8]) { //~ ERROR mismatched types
ref x => {} ref x => {}
} }
let _len = (arr: &[u8]).len(); //~ ERROR mismatched types let _len = type_ascribe!(arr, &[u8]).len(); //~ ERROR mismatched types
} }

View file

@ -1,35 +1,35 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/type-ascription-soundness.rs:7:17 --> $DIR/type-ascription-soundness.rs:7:31
| |
LL | let ref x = arr: &[u8]; LL | let ref x = type_ascribe!(arr, &[u8]);
| ^^^ expected slice `[u8]`, found array `[u8; 3]` | ^^^ expected slice `[u8]`, found array `[u8; 3]`
| |
= note: expected reference `&[u8]` = note: expected reference `&[u8]`
found reference `&[u8; 3]` found reference `&[u8; 3]`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/type-ascription-soundness.rs:8:21 --> $DIR/type-ascription-soundness.rs:8:35
| |
LL | let ref mut x = arr: &[u8]; LL | let ref mut x = type_ascribe!(arr, &[u8]);
| ^^^ expected slice `[u8]`, found array `[u8; 3]` | ^^^ expected slice `[u8]`, found array `[u8; 3]`
| |
= note: expected reference `&[u8]` = note: expected reference `&[u8]`
found reference `&[u8; 3]` found reference `&[u8; 3]`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/type-ascription-soundness.rs:9:11 --> $DIR/type-ascription-soundness.rs:9:25
| |
LL | match arr: &[u8] { LL | match type_ascribe!(arr, &[u8]) {
| ^^^ expected slice `[u8]`, found array `[u8; 3]` | ^^^ expected slice `[u8]`, found array `[u8; 3]`
| |
= note: expected reference `&[u8]` = note: expected reference `&[u8]`
found reference `&[u8; 3]` found reference `&[u8; 3]`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/type-ascription-soundness.rs:12:17 --> $DIR/type-ascription-soundness.rs:12:30
| |
LL | let _len = (arr: &[u8]).len(); LL | let _len = type_ascribe!(arr, &[u8]).len();
| ^^^ expected slice `[u8]`, found array `[u8; 3]` | ^^^ expected slice `[u8]`, found array `[u8; 3]`
| |
= note: expected reference `&[u8]` = note: expected reference `&[u8]`
found reference `&[u8; 3]` found reference `&[u8; 3]`

View file

@ -8,32 +8,32 @@
use std::mem; use std::mem;
const C1: u8 = 10: u8; const C1: u8 = type_ascribe!(10, u8);
const C2: [u8; 1: usize] = [1]; const C2: [u8; type_ascribe!(1, usize)] = [1];
struct S { struct S {
a: u8 a: u8
} }
fn main() { fn main() {
assert_eq!(C1.into(): i32, 10); assert_eq!(type_ascribe!(C1.into(), i32), 10);
assert_eq!(C2[0], 1); assert_eq!(C2[0], 1);
let s = S { a: 10: u8 }; let s = S { a: type_ascribe!(10, u8) };
let arr = &[1u8, 2, 3]; let arr = &[1u8, 2, 3];
let mut v = arr.iter().cloned().collect(): Vec<_>; let mut v = type_ascribe!(arr.iter().cloned().collect(), Vec<_>);
v.push(4); v.push(4);
assert_eq!(v, [1, 2, 3, 4]); assert_eq!(v, [1, 2, 3, 4]);
let a = 1: u8; let a = type_ascribe!(1, u8);
let b = a.into(): u16; let b = type_ascribe!(a.into(), u16);
assert_eq!(v[a.into(): usize], 2); assert_eq!(v[type_ascribe!(a.into(), usize)], 2);
assert_eq!(mem::size_of_val(&a), 1); assert_eq!(mem::size_of_val(&a), 1);
assert_eq!(mem::size_of_val(&b), 2); assert_eq!(mem::size_of_val(&b), 2);
assert_eq!(b, 1: u16); assert_eq!(b, type_ascribe!(1, u16));
let mut v = Vec::new(); let mut v = Vec::new();
v: Vec<u8> = vec![1, 2, 3]; // Place expression type ascription type_ascribe!(v, Vec<u8>) = vec![1, 2, 3]; // Place expression type ascription
assert_eq!(v, [1u8, 2, 3]); assert_eq!(v, [1u8, 2, 3]);
} }

View file

@ -1,5 +1,7 @@
#![feature(type_ascription)]
fn main() { fn main() {
0: u8<e<5>=e> type_ascribe!(0, u8<e<5>=e>)
//~^ ERROR: cannot find type `e` in this scope [E0412] //~^ ERROR: cannot find type `e` in this scope [E0412]
//~| ERROR: associated type bindings are not allowed here [E0229] //~| ERROR: associated type bindings are not allowed here [E0229]
//~| ERROR: mismatched types [E0308] //~| ERROR: mismatched types [E0308]

View file

@ -1,25 +1,22 @@
error[E0412]: cannot find type `e` in this scope error[E0412]: cannot find type `e` in this scope
--> $DIR/issue-91267.rs:2:16 --> $DIR/issue-91267.rs:4:30
| |
LL | 0: u8<e<5>=e> LL | type_ascribe!(0, u8<e<5>=e>)
| ^ | ^ not found in this scope
| |
| not found in this scope
| help: maybe you meant to write an assignment here: `let e`
error[E0229]: associated type bindings are not allowed here error[E0229]: associated type bindings are not allowed here
--> $DIR/issue-91267.rs:2:11 --> $DIR/issue-91267.rs:4:25
| |
LL | 0: u8<e<5>=e> LL | type_ascribe!(0, u8<e<5>=e>)
| ^^^^^^ associated type not allowed here | ^^^^^^ associated type not allowed here
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-91267.rs:2:5 --> $DIR/issue-91267.rs:4:5
| |
LL | fn main() { LL | fn main() {
| - expected `()` because of default return type | - expected `()` because of default return type
LL | 0: u8<e<5>=e> LL | type_ascribe!(0, u8<e<5>=e>)
| ^^^^^^^^^^^^^ expected `()`, found `u8` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `u8`
error: aborting due to 3 previous errors error: aborting due to 3 previous errors