Skip to content

Commit

Permalink
Rollup merge of rust-lang#104614 - Nilstrieb:type-ascribe!, r=TaKO8Ki
Browse files Browse the repository at this point in the history
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 rust-lang#101728
  • Loading branch information
matthiaskrgr authored Dec 2, 2022
2 parents 11663b1 + efea79c commit 4fdc3eb
Show file tree
Hide file tree
Showing 32 changed files with 265 additions and 224 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_builtin_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ mod log_syntax;
mod source_util;
mod test;
mod trace_macros;
mod type_ascribe;
mod util;

pub mod asm;
Expand Down Expand Up @@ -92,6 +93,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
unreachable: edition_panic::expand_unreachable,
stringify: source_util::expand_stringify,
trace_macros: trace_macros::expand_trace_macros,
type_ascribe: type_ascribe::expand_type_ascribe,
}

register_attr! {
Expand Down
35 changes: 35 additions & 0 deletions compiler/rustc_builtin_macros/src/type_ascribe.rs
Original file line number Diff line number Diff line change
@@ -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))
}
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,7 @@ symbols! {
ty,
type_alias_enum_variants,
type_alias_impl_trait,
type_ascribe,
type_ascription,
type_changing_struct_update,
type_id,
Expand Down
12 changes: 12 additions & 0 deletions library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,18 @@ pub(crate) mod builtin {
/* 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.
#[rustc_builtin_macro]
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
8 changes: 8 additions & 0 deletions library/core/src/prelude/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,11 @@ pub use crate::macros::builtin::cfg_accessible;
reason = "`cfg_eval` is a recently implemented feature"
)]
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;
9 changes: 9 additions & 0 deletions library/std/src/prelude/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ pub use core::prelude::v1::cfg_accessible;
)]
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,
// and below to src/liballoc/prelude.rs.
// Those files are duplicated rather than using glob imports
Expand Down
8 changes: 5 additions & 3 deletions src/test/ui/associated-consts/issue-93835.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#![feature(type_ascription)]

fn e() {
p:a<p:p<e=6>>
//~^ ERROR comparison operators
type_ascribe!(p, a<p:p<e=6>>);
//~^ ERROR cannot find type `a` in this scope
//~| ERROR cannot find value
//~| ERROR associated const equality
//~| ERROR associated const equality
//~| ERROR cannot find trait `p` in this scope
//~| ERROR associated type bounds
}

Expand Down
65 changes: 20 additions & 45 deletions src/test/ui/associated-consts/issue-93835.stderr
Original file line number Diff line number Diff line change
@@ -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
--> $DIR/issue-93835.rs:2:5
|
LL | p:a<p:p<e=6>>
| ^ not found in this scope
|
help: you might have meant to write a `struct` literal
|
LL ~ fn e() { SomeStruct {
LL | p:a<p:p<e=6>>
...
LL |
LL ~ }}
--> $DIR/issue-93835.rs:4:19
|
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>>
| ~~~~~
LL | type_ascribe!(p, a<p:p<e=6>>);
| ^ not found in this scope

error[E0658]: associated const equality is incomplete
--> $DIR/issue-93835.rs:2:13
error[E0412]: cannot find type `a` in this scope
--> $DIR/issue-93835.rs:4:22
|
LL | p:a<p:p<e=6>>
| ^^^
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
|
= 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
LL | type_ascribe!(p, a<p:p<e=6>>);
| ^ not found in this scope

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 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
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0425, E0658.
For more information about an error, try `rustc --explain E0425`.
Some errors have detailed explanations: E0405, E0412, E0425, E0658.
For more information about an error, try `rustc --explain E0405`.
4 changes: 3 additions & 1 deletion src/test/ui/closures/issue-90871.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#![feature(type_ascription)]

fn main() {
2: n([u8; || 1])
type_ascribe!(2, n([u8; || 1]))
//~^ ERROR cannot find type `n` in this scope
//~| ERROR mismatched types
}
23 changes: 14 additions & 9 deletions src/test/ui/closures/issue-90871.stderr
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
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])
| ^ expecting a type here because of type ascription
LL | type_ascribe!(2, n([u8; || 1]))
| ^ 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
--> $DIR/issue-90871.rs:2:15
--> $DIR/issue-90871.rs:4:29
|
LL | 2: n([u8; || 1])
| ^^^^ expected `usize`, found closure
LL | type_ascribe!(2, n([u8; || 1]))
| ^^^^ expected `usize`, found closure
|
= 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
|
LL | 2: n([u8; (|| 1)()])
| + +++
LL | type_ascribe!(2, n([u8; (|| 1)()]))
| + +++

error: aborting due to 2 previous errors

Expand Down
32 changes: 16 additions & 16 deletions src/test/ui/coercion/coerce-expect-unsized-ascribed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@
use std::fmt::Debug;

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

0 comments on commit 4fdc3eb

Please sign in to comment.