diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 5831636a81b2c..3d51770f6ba79 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -510,6 +510,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(try_blocks_heterogeneous, "`try bikeshed` expression is experimental"); gate_all!(unsafe_binders, "unsafe binder types are experimental"); gate_all!(unsafe_fields, "`unsafe` fields are experimental"); + gate_all!(view_types, "view types are experimental"); gate_all!(where_clause_attrs, "attributes in `where` clause are unstable"); gate_all!(yeet_expr, "`do yeet` expression is experimental"); // tidy-alphabetical-end diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 3bb4bc863def2..9712879fce6f7 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -723,6 +723,8 @@ declare_features! ( (internal, unsized_fn_params, "1.49.0", Some(48055)), /// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute. (unstable, used_with_arg, "1.60.0", Some(93798)), + /// Allows view types. + (unstable, view_types, "CURRENT_RUSTC_VERSION", Some(155938)), /// Target features on wasm. (unstable, wasm_target_feature, "1.30.0", Some(150260)), /// Allows use of attributes in `where` clauses. diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 072975f445bf4..b5151cf20ab02 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -19,7 +19,7 @@ use crate::errors::{ NeedPlusAfterTraitObjectLifetime, NestedCVariadicType, ReturnTypesUseThinArrow, }; use crate::parser::item::FrontMatterParsingMode; -use crate::parser::{FnContext, FnParseMode}; +use crate::parser::{ExpTokenPair, FnContext, FnParseMode}; use crate::{exp, maybe_recover_from_interpolated_ty_qpath}; /// Signals whether parsing a type should allow `+`. @@ -768,6 +768,25 @@ impl<'a> Parser<'a> { self.bump_with((dyn_tok, dyn_tok_sp)); } let ty = self.parse_ty_no_plus()?; + if self.token == TokenKind::Dot && self.look_ahead(1, |t| t.kind == TokenKind::OpenBrace) { + // & [mut] . { } + // ^ + // we are here + let view_start_span = self.token.span; + self.bump(); + let fields = self + .parse_delim_comma_seq( + ExpTokenPair { tok: TokenKind::OpenBrace, token_type: TokenType::OpenBrace }, + ExpTokenPair { tok: TokenKind::CloseBrace, token_type: TokenType::CloseBrace }, + |p| p.parse_ident(), + )? + .0; + // FIXME(scrabsha): actually propagate field view in the AST. + let _ = fields; + let view_end_span = self.prev_token.span; + let span = view_start_span.to(view_end_span); + self.psess.gated_spans.gate(sym::view_types, span); + } Ok(match pinned { Pinnedness::Not => TyKind::Ref(opt_lifetime, MutTy { ty, mutbl }), Pinnedness::Pinned => TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl }), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4cacdbd3408a5..3db4921d6ec0a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2232,6 +2232,7 @@ symbols! { verbatim, version, vfp2, + view_types, vis, visible_private_types, volatile, diff --git a/tests/ui/feature-gates/feature-gate-view-types.rs b/tests/ui/feature-gates/feature-gate-view-types.rs new file mode 100644 index 0000000000000..eb0c26d61db4a --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-view-types.rs @@ -0,0 +1,17 @@ +struct Foo { + a: usize, + b: usize, +} + +fn bar(a: &mut Foo.{ a }, b: &mut Foo.{ b }) { + //~^ ERROR view types are experimental + //~| ERROR view types are experimental + a.a += 1; + b.b += 1; +} + +fn main() { + let mut foo = Foo { a: 0, b: 0 }; + bar(&mut foo, &mut foo); + //~^ ERROR cannot borrow `foo` as mutable more than once at a time +} diff --git a/tests/ui/feature-gates/feature-gate-view-types.stderr b/tests/ui/feature-gates/feature-gate-view-types.stderr new file mode 100644 index 0000000000000..661783ec59202 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-view-types.stderr @@ -0,0 +1,33 @@ +error[E0658]: view types are experimental + --> $DIR/feature-gate-view-types.rs:6:19 + | +LL | fn bar(a: &mut Foo.{ a }, b: &mut Foo.{ b }) { + | ^^^^^^ + | + = note: see issue #155938 for more information + = help: add `#![feature(view_types)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: view types are experimental + --> $DIR/feature-gate-view-types.rs:6:38 + | +LL | fn bar(a: &mut Foo.{ a }, b: &mut Foo.{ b }) { + | ^^^^^^ + | + = note: see issue #155938 for more information + = help: add `#![feature(view_types)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0499]: cannot borrow `foo` as mutable more than once at a time + --> $DIR/feature-gate-view-types.rs:15:19 + | +LL | bar(&mut foo, &mut foo); + | --- -------- ^^^^^^^^ second mutable borrow occurs here + | | | + | | first mutable borrow occurs here + | first borrow later used by call + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0499, E0658. +For more information about an error, try `rustc --explain E0499`.