From d3992fac9491d397f8d41d7f34f98f1420d7728f Mon Sep 17 00:00:00 2001 From: Sasha Pourcelot Date: Tue, 28 Apr 2026 18:01:12 +0000 Subject: [PATCH 1/2] Add feature gate for view_types --- compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_span/src/symbol.rs | 1 + .../feature-gates/feature-gate-view-types.rs | 16 ++++++ .../feature-gate-view-types.stderr | 49 +++++++++++++++++++ 4 files changed, 68 insertions(+) create mode 100644 tests/ui/feature-gates/feature-gate-view-types.rs create mode 100644 tests/ui/feature-gates/feature-gate-view-types.stderr 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_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..26ca0ee4206b2 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-view-types.rs @@ -0,0 +1,16 @@ +//@ known-bug: #155938 + +struct Foo { + a: usize, + b: usize, +} + +fn bar(a: &mut Foo.{ a }, b: &mut Foo.{ b }) { + a.a += 1; + b.b += 1; +} + +fn main() { + let mut foo = Foo { a: 0, b: 0 }; + bar(&mut foo, &mut foo); +} 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..436b7ea769ed3 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-view-types.stderr @@ -0,0 +1,49 @@ +error: expected parameter name, found `{` + --> $DIR/feature-gate-view-types.rs:8:20 + | +LL | fn bar(a: &mut Foo.{ a }, b: &mut Foo.{ b }) { + | ^ expected parameter name + +error: expected one of `!`, `(`, `)`, `,`, `::`, or `<`, found `.` + --> $DIR/feature-gate-view-types.rs:8:19 + | +LL | fn bar(a: &mut Foo.{ a }, b: &mut Foo.{ b }) { + | ^ + | | + | expected one of `!`, `(`, `)`, `,`, `::`, or `<` + | help: missing `,` + +error: expected parameter name, found `{` + --> $DIR/feature-gate-view-types.rs:8:39 + | +LL | fn bar(a: &mut Foo.{ a }, b: &mut Foo.{ b }) { + | ^ expected parameter name + +error: expected one of `!`, `(`, `)`, `,`, `::`, or `<`, found `.` + --> $DIR/feature-gate-view-types.rs:8:38 + | +LL | fn bar(a: &mut Foo.{ a }, b: &mut Foo.{ b }) { + | ^ + | | + | expected one of `!`, `(`, `)`, `,`, `::`, or `<` + | help: missing `,` + +error[E0061]: this function takes 4 arguments but 2 arguments were supplied + --> $DIR/feature-gate-view-types.rs:15:5 + | +LL | bar(&mut foo, &mut foo); + | ^^^-------------------- two arguments are missing + | +note: function defined here + --> $DIR/feature-gate-view-types.rs:8:4 + | +LL | fn bar(a: &mut Foo.{ a }, b: &mut Foo.{ b }) { + | ^^^ ----------------- +help: provide the arguments + | +LL | bar(&mut foo, &mut foo, /* &mut Foo */, /* _ */); + | +++++++++++++++++++++++++ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0061`. From 77fb8d1d5c5f5e2058049b3b90abde3f8bccef4f Mon Sep 17 00:00:00 2001 From: Sasha Pourcelot Date: Wed, 29 Apr 2026 09:03:26 +0000 Subject: [PATCH 2/2] Parse view type syntax, mark it as unstable --- compiler/rustc_ast_passes/src/feature_gate.rs | 1 + compiler/rustc_parse/src/parser/ty.rs | 21 ++++++- .../feature-gates/feature-gate-view-types.rs | 5 +- .../feature-gate-view-types.stderr | 58 +++++++------------ 4 files changed, 45 insertions(+), 40 deletions(-) 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_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/tests/ui/feature-gates/feature-gate-view-types.rs b/tests/ui/feature-gates/feature-gate-view-types.rs index 26ca0ee4206b2..eb0c26d61db4a 100644 --- a/tests/ui/feature-gates/feature-gate-view-types.rs +++ b/tests/ui/feature-gates/feature-gate-view-types.rs @@ -1,11 +1,11 @@ -//@ known-bug: #155938 - 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; } @@ -13,4 +13,5 @@ fn bar(a: &mut Foo.{ a }, b: &mut Foo.{ b }) { 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 index 436b7ea769ed3..661783ec59202 100644 --- a/tests/ui/feature-gates/feature-gate-view-types.stderr +++ b/tests/ui/feature-gates/feature-gate-view-types.stderr @@ -1,49 +1,33 @@ -error: expected parameter name, found `{` - --> $DIR/feature-gate-view-types.rs:8:20 +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 }) { - | ^ expected parameter name - -error: expected one of `!`, `(`, `)`, `,`, `::`, or `<`, found `.` - --> $DIR/feature-gate-view-types.rs:8:19 + | ^^^^^^ | -LL | fn bar(a: &mut Foo.{ a }, b: &mut Foo.{ b }) { - | ^ - | | - | expected one of `!`, `(`, `)`, `,`, `::`, or `<` - | help: missing `,` + = 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: expected parameter name, found `{` - --> $DIR/feature-gate-view-types.rs:8:39 +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 }) { - | ^ expected parameter name - -error: expected one of `!`, `(`, `)`, `,`, `::`, or `<`, found `.` - --> $DIR/feature-gate-view-types.rs:8:38 + | ^^^^^^ | -LL | fn bar(a: &mut Foo.{ a }, b: &mut Foo.{ b }) { - | ^ - | | - | expected one of `!`, `(`, `)`, `,`, `::`, or `<` - | help: missing `,` + = 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[E0061]: this function takes 4 arguments but 2 arguments were supplied - --> $DIR/feature-gate-view-types.rs:15:5 +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); - | ^^^-------------------- two arguments are missing - | -note: function defined here - --> $DIR/feature-gate-view-types.rs:8:4 - | -LL | fn bar(a: &mut Foo.{ a }, b: &mut Foo.{ b }) { - | ^^^ ----------------- -help: provide the arguments - | -LL | bar(&mut foo, &mut foo, /* &mut Foo */, /* _ */); - | +++++++++++++++++++++++++ + | --- -------- ^^^^^^^^ second mutable borrow occurs here + | | | + | | first mutable borrow occurs here + | first borrow later used by call -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0061`. +Some errors have detailed explanations: E0499, E0658. +For more information about an error, try `rustc --explain E0499`.