Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #131724

Merged
merged 20 commits into from
Oct 15, 2024
Merged
Changes from 4 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3025513
Implemented FromStr for CString and TryFrom<CString> for String
YohDeadfall Sep 20, 2024
5fef462
Add 1.82 release notes
Mark-Simulacrum Oct 2, 2024
a0e687f
Remove unnecessary sorts in `rustc_hir_analysis`.
ismailarilik Oct 6, 2024
ae698f8
Add sugar for &pin (const|mut) types
eholk Sep 20, 2024
b490bf5
Fix clippy and rustfmt compilation
eholk Sep 20, 2024
3aabe1e
Add basic pin sugar support to rustfmt
eholk Sep 23, 2024
005a629
re-sync with latest tracking issue changes
Mark-Simulacrum Oct 7, 2024
cae29b2
Import another update
Mark-Simulacrum Oct 12, 2024
276d112
Add stabilized APIs
Mark-Simulacrum Oct 12, 2024
5b2985f
Add explicit link to PR
Mark-Simulacrum Oct 12, 2024
4e438f7
Fix two const-hacks
GKFX Oct 14, 2024
10aa255
improve error messages for `C-cmse-nonsecure-entry` functions
folkertdev Oct 14, 2024
3c31729
Stabilise 'const_make_ascii'
bjoernager Oct 9, 2024
3a00d35
Rollup merge of #130608 - YohDeadfall:cstr-from-into-str, r=workingju…
matthiaskrgr Oct 15, 2024
fb691b4
Rollup merge of #130635 - eholk:pin-reborrow-sugar, r=compiler-errors
matthiaskrgr Oct 15, 2024
731e360
Rollup merge of #130747 - folkertdev:c-cmse-nonsecure-entry-error-mes…
matthiaskrgr Oct 15, 2024
13e07b9
Rollup merge of #131137 - Mark-Simulacrum:relnotes, r=cuviper
matthiaskrgr Oct 15, 2024
b9cb201
Rollup merge of #131328 - ismailarilik:remove-unnecessary-sorts-in-ru…
matthiaskrgr Oct 15, 2024
9716a42
Rollup merge of #131496 - bjoernager:const-make-ascii, r=dtolnay
matthiaskrgr Oct 15, 2024
83252bd
Rollup merge of #131706 - GKFX:fix-const-hacks, r=tgross35
matthiaskrgr Oct 15, 2024
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
11 changes: 9 additions & 2 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ use std::{cmp, fmt, mem};

pub use GenericArgs::*;
pub use UnsafeSource::*;
pub use rustc_ast_ir::{Movability, Mutability};
pub use rustc_ast_ir::{Movability, Mutability, Pinnedness};
use rustc_data_structures::packed::Pu128;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -2161,6 +2161,10 @@ pub enum TyKind {
Ptr(MutTy),
/// A reference (`&'a T` or `&'a mut T`).
Ref(Option<Lifetime>, MutTy),
/// A pinned reference (`&'a pin const T` or `&'a pin mut T`).
///
/// Desugars into `Pin<&'a T>` or `Pin<&'a mut T>`.
PinnedRef(Option<Lifetime>, MutTy),
/// A bare function (e.g., `fn(usize) -> bool`).
BareFn(P<BareFnTy>),
/// The never type (`!`).
@@ -2501,7 +2505,10 @@ impl Param {
if ident.name == kw::SelfLower {
return match self.ty.kind {
TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
TyKind::Ref(lt, MutTy { ref ty, mutbl })
| TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
if ty.kind.is_implicit_self() =>
{
Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
}
_ => Some(respan(
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
@@ -485,7 +485,7 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
}
TyKind::Slice(ty) => vis.visit_ty(ty),
TyKind::Ptr(mt) => vis.visit_mt(mt),
TyKind::Ref(lt, mt) => {
TyKind::Ref(lt, mt) | TyKind::PinnedRef(lt, mt) => {
visit_opt(lt, |lt| vis.visit_lifetime(lt));
vis.visit_mt(mt);
}
4 changes: 3 additions & 1 deletion compiler/rustc_ast/src/util/classify.rs
Original file line number Diff line number Diff line change
@@ -247,7 +247,9 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> {
break (mac.args.delim == Delimiter::Brace).then_some(mac);
}

ast::TyKind::Ptr(mut_ty) | ast::TyKind::Ref(_, mut_ty) => {
ast::TyKind::Ptr(mut_ty)
| ast::TyKind::Ref(_, mut_ty)
| ast::TyKind::PinnedRef(_, mut_ty) => {
ty = &mut_ty.ty;
}

3 changes: 2 additions & 1 deletion compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
@@ -499,7 +499,8 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
match kind {
TyKind::Slice(ty) | TyKind::Paren(ty) => try_visit!(visitor.visit_ty(ty)),
TyKind::Ptr(MutTy { ty, mutbl: _ }) => try_visit!(visitor.visit_ty(ty)),
TyKind::Ref(opt_lifetime, MutTy { ty, mutbl: _ }) => {
TyKind::Ref(opt_lifetime, MutTy { ty, mutbl: _ })
| TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl: _ }) => {
visit_opt!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Ref);
try_visit!(visitor.visit_ty(ty));
}
7 changes: 7 additions & 0 deletions compiler/rustc_ast_ir/src/lib.rs
Original file line number Diff line number Diff line change
@@ -79,3 +79,10 @@ impl Mutability {
matches!(self, Self::Not)
}
}

#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
pub enum Pinnedness {
Not,
Pinned,
}
5 changes: 3 additions & 2 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
@@ -640,7 +640,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_span(span),
Some(self.allow_gen_future.clone()),
);
let resume_ty = self.make_lang_item_qpath(hir::LangItem::ResumeTy, unstable_span);
let resume_ty =
self.make_lang_item_qpath(hir::LangItem::ResumeTy, unstable_span, None);
let input_ty = hir::Ty {
hir_id: self.next_id(),
kind: hir::TyKind::Path(resume_ty),
@@ -2065,7 +2066,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
lang_item: hir::LangItem,
name: Symbol,
) -> hir::Expr<'hir> {
let qpath = self.make_lang_item_qpath(lang_item, self.lower_span(span));
let qpath = self.make_lang_item_qpath(lang_item, self.lower_span(span), None);
let path = hir::ExprKind::Path(hir::QPath::TypeRelative(
self.arena.alloc(self.ty(span, hir::TyKind::Path(qpath))),
self.arena.alloc(hir::PathSegment::new(
51 changes: 43 additions & 8 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
@@ -55,8 +55,8 @@ use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, StashKey};
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalDefIdMap};
use rustc_hir::{
self as hir, ConstArg, GenericArg, HirId, ItemLocalMap, MissingLifetimeKind, ParamName,
TraitCandidate,
self as hir, ConstArg, GenericArg, HirId, ItemLocalMap, LangItem, MissingLifetimeKind,
ParamName, TraitCandidate,
};
use rustc_index::{Idx, IndexSlice, IndexVec};
use rustc_macros::extension;
@@ -765,8 +765,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
res
}

fn make_lang_item_qpath(&mut self, lang_item: hir::LangItem, span: Span) -> hir::QPath<'hir> {
hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, None))
fn make_lang_item_qpath(
&mut self,
lang_item: hir::LangItem,
span: Span,
args: Option<&'hir hir::GenericArgs<'hir>>,
) -> hir::QPath<'hir> {
hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, args))
}

fn make_lang_item_path(
@@ -1277,6 +1282,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let lifetime = self.lower_lifetime(&region);
hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))
}
TyKind::PinnedRef(region, mt) => {
let region = region.unwrap_or_else(|| {
let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
self.resolver.get_lifetime_res(t.id)
{
debug_assert_eq!(start.plus(1), end);
start
} else {
self.next_node_id()
};
let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
});
let lifetime = self.lower_lifetime(&region);
let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));
let span = self.lower_span(t.span);
let arg = hir::Ty { kind, span, hir_id: self.next_id() };
let args = self.arena.alloc(hir::GenericArgs {
args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),
constraints: &[],
parenthesized: hir::GenericArgsParentheses::No,
span_ext: span,
});
let path = self.make_lang_item_qpath(LangItem::Pin, span, Some(args));
hir::TyKind::Path(path)
}
TyKind::BareFn(f) => {
let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy {
@@ -1845,10 +1876,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Given we are only considering `ImplicitSelf` types, we needn't consider
// the case where we have a mutable pattern to a reference as that would
// no longer be an `ImplicitSelf`.
TyKind::Ref(_, mt) if mt.ty.kind.is_implicit_self() => match mt.mutbl {
hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,
hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,
},
TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)
if mt.ty.kind.is_implicit_self() =>
{
match mt.mutbl {
hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,
hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,
}
}
_ => hir::ImplicitSelfKind::None,
}
}),
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/lifetime_collector.rs
Original file line number Diff line number Diff line change
@@ -95,7 +95,7 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> {
visit::walk_ty(self, t);
self.current_binders.pop();
}
TyKind::Ref(None, _) => {
TyKind::Ref(None, _) | TyKind::PinnedRef(None, _) => {
self.record_elided_anchor(t.id, t.span);
visit::walk_ty(self, t);
}
1 change: 1 addition & 0 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
@@ -546,6 +546,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
gate_all!(mut_ref, "mutable by-reference bindings are experimental");
gate_all!(global_registration, "global registration is experimental");
gate_all!(return_type_notation, "return type notation is experimental");
gate_all!(pin_ergonomics, "pinned reference syntax is experimental");

if !visitor.features.never_patterns {
if let Some(spans) = spans.get(&sym::never_patterns) {
6 changes: 6 additions & 0 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
@@ -1163,6 +1163,12 @@ impl<'a> State<'a> {
self.print_opt_lifetime(lifetime);
self.print_mt(mt, false);
}
ast::TyKind::PinnedRef(lifetime, mt) => {
self.word("&");
self.print_opt_lifetime(lifetime);
self.word("pin ");
self.print_mt(mt, true);
}
ast::TyKind::Never => {
self.word("!");
}
5 changes: 2 additions & 3 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use std::fmt;

use rustc_ast as ast;
use rustc_ast::util::parser::ExprPrecedence;
use rustc_ast::{
Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label, LitKind,
TraitObjectSyntax, UintTy,
self as ast, Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label,
LitKind, TraitObjectSyntax, UintTy,
};
pub use rustc_ast::{
BinOp, BinOpKind, BindingMode, BorrowKind, ByRef, CaptureBy, ImplPolarity, IsAuto, Movability,
38 changes: 35 additions & 3 deletions compiler/rustc_parse/src/parser/ty.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,8 @@ use rustc_ast::util::case::Case;
use rustc_ast::{
self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy,
GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability,
PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind,
Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty,
TyKind,
};
use rustc_errors::{Applicability, PResult};
use rustc_span::symbol::{Ident, kw, sym};
@@ -487,7 +488,10 @@ impl<'a> Parser<'a> {
fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
let and_span = self.prev_token.span;
let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime());
let mut mutbl = self.parse_mutability();
let (pinned, mut mutbl) = match self.parse_pin_and_mut() {
Some(pin_mut) => pin_mut,
None => (Pinnedness::Not, self.parse_mutability()),
};
if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() {
// A lifetime is invalid here: it would be part of a bare trait bound, which requires
// it to be followed by a plus, but we disallow plus in the pointee type.
@@ -523,7 +527,35 @@ impl<'a> Parser<'a> {
self.bump_with((dyn_tok, dyn_tok_sp));
}
let ty = self.parse_ty_no_plus()?;
Ok(TyKind::Ref(opt_lifetime, MutTy { ty, mutbl }))
Ok(match pinned {
Pinnedness::Not => TyKind::Ref(opt_lifetime, MutTy { ty, mutbl }),
Pinnedness::Pinned => TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl }),
})
}

/// Parses `pin` and `mut` annotations on references.
///
/// It must be either `pin const` or `pin mut`.
pub(crate) fn parse_pin_and_mut(&mut self) -> Option<(Pinnedness, Mutability)> {
if self.token.is_ident_named(sym::pin) {
let result = self.look_ahead(1, |token| {
if token.is_keyword(kw::Const) {
Some((Pinnedness::Pinned, Mutability::Not))
} else if token.is_keyword(kw::Mut) {
Some((Pinnedness::Pinned, Mutability::Mut))
} else {
None
}
});
if result.is_some() {
self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
self.bump();
self.bump();
}
result
} else {
None
}
}

// Parses the `typeof(EXPR)`.
1 change: 1 addition & 0 deletions compiler/rustc_passes/src/hir_stats.rs
Original file line number Diff line number Diff line change
@@ -579,6 +579,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
Array,
Ptr,
Ref,
PinnedRef,
BareFn,
Never,
Tup,
4 changes: 2 additions & 2 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
@@ -779,7 +779,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
let prev = self.diag_metadata.current_trait_object;
let prev_ty = self.diag_metadata.current_type_path;
match &ty.kind {
TyKind::Ref(None, _) => {
TyKind::Ref(None, _) | TyKind::PinnedRef(None, _) => {
// Elided lifetime in reference: we resolve as if there was some lifetime `'_` with
// NodeId `ty.id`.
// This span will be used in case of elision failure.
@@ -2326,7 +2326,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
impl<'ra> Visitor<'ra> for FindReferenceVisitor<'_, '_, '_> {
fn visit_ty(&mut self, ty: &'ra Ty) {
trace!("FindReferenceVisitor considering ty={:?}", ty);
if let TyKind::Ref(lt, _) = ty.kind {
if let TyKind::Ref(lt, _) | TyKind::PinnedRef(lt, _) = ty.kind {
// See if anything inside the &thing contains Self
let mut visitor =
SelfVisitor { r: self.r, impl_self: self.impl_self, self_found: false };
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -3482,7 +3482,7 @@ struct LifetimeFinder<'ast> {

impl<'ast> Visitor<'ast> for LifetimeFinder<'ast> {
fn visit_ty(&mut self, t: &'ast Ty) {
if let TyKind::Ref(_, mut_ty) = &t.kind {
if let TyKind::Ref(_, mut_ty) | TyKind::PinnedRef(_, mut_ty) = &t.kind {
self.seen.push(t);
if t.span.lo() == self.lifetime.lo() {
self.found = Some(&mut_ty.ty);
3 changes: 3 additions & 0 deletions src/tools/clippy/clippy_utils/src/ast_utils.rs
Original file line number Diff line number Diff line change
@@ -753,6 +753,9 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool {
(Ref(ll, l), Ref(rl, r)) => {
both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty)
},
(PinnedRef(ll, l), PinnedRef(rl, r)) => {
both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty)
},
(BareFn(l), BareFn(r)) => {
l.safety == r.safety
&& eq_ext(&l.ext, &r.ext)
16 changes: 12 additions & 4 deletions src/tools/rustfmt/src/types.rs
Original file line number Diff line number Diff line change
@@ -827,7 +827,8 @@ impl Rewrite for ast::Ty {

rewrite_unary_prefix(context, prefix, &*mt.ty, shape)
}
ast::TyKind::Ref(ref lifetime, ref mt) => {
ast::TyKind::Ref(ref lifetime, ref mt)
| ast::TyKind::PinnedRef(ref lifetime, ref mt) => {
let mut_str = format_mutability(mt.mutbl);
let mut_len = mut_str.len();
let mut result = String::with_capacity(128);
@@ -861,6 +862,13 @@ impl Rewrite for ast::Ty {
cmnt_lo = lifetime.ident.span.hi();
}

if let ast::TyKind::PinnedRef(..) = self.kind {
result.push_str("pin ");
if ast::Mutability::Not == mt.mutbl {
result.push_str("const ");
}
}

if ast::Mutability::Mut == mt.mutbl {
let mut_hi = context.snippet_provider.span_after(self.span(), "mut");
let before_mut_span = mk_sp(cmnt_lo, mut_hi - BytePos::from_usize(3));
@@ -1260,9 +1268,9 @@ pub(crate) fn can_be_overflowed_type(
) -> bool {
match ty.kind {
ast::TyKind::Tup(..) => context.use_block_indent() && len == 1,
ast::TyKind::Ref(_, ref mutty) | ast::TyKind::Ptr(ref mutty) => {
can_be_overflowed_type(context, &*mutty.ty, len)
}
ast::TyKind::Ref(_, ref mutty)
| ast::TyKind::PinnedRef(_, ref mutty)
| ast::TyKind::Ptr(ref mutty) => can_be_overflowed_type(context, &*mutty.ty, len),
_ => false,
}
}
10 changes: 10 additions & 0 deletions src/tools/rustfmt/tests/source/pin_sugar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// See #130494

#![feature(pin_ergonomics)]
#![allow(incomplete_features)]

fn f(x: &pin const i32) {}
fn g<'a>(x: & 'a pin const i32) {}
fn h<'a>(x: & 'a pin
mut i32) {}
fn i(x: &pin mut i32) {}
9 changes: 9 additions & 0 deletions src/tools/rustfmt/tests/target/pin_sugar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// See #130494

#![feature(pin_ergonomics)]
#![allow(incomplete_features)]

fn f(x: &pin const i32) {}
fn g<'a>(x: &'a pin const i32) {}
fn h<'a>(x: &'a pin mut i32) {}
fn i(x: &pin mut i32) {}
15 changes: 15 additions & 0 deletions tests/ui/async-await/pin-sugar-ambiguity.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//@ check-pass
#![feature(pin_ergonomics)]
#![allow(dead_code, incomplete_features)]

// Handle the case where there's ambiguity between pin as a contextual keyword and pin as a path.

struct Foo;

mod pin {
pub struct Foo;
}

fn main() {
let _x: &pin ::Foo = &pin::Foo;
}
8 changes: 8 additions & 0 deletions tests/ui/async-await/pin-sugar-no-const.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#![feature(pin_ergonomics)]
#![allow(incomplete_features)]

// Makes sure we don't accidentally accept `&pin Foo` without the `const` keyword.

fn main() {
let _x: &pin i32 = todo!(); //~ ERROR found `i32`
}
15 changes: 15 additions & 0 deletions tests/ui/async-await/pin-sugar-no-const.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error: expected one of `!`, `(`, `::`, `;`, `<`, or `=`, found `i32`
--> $DIR/pin-sugar-no-const.rs:7:18
|
LL | let _x: &pin i32 = todo!();
| - ^^^ expected one of `!`, `(`, `::`, `;`, `<`, or `=`
| |
| while parsing the type for `_x`
|
help: there is a keyword `in` with a similar name
|
LL | let _x: &in i32 = todo!();
| ~~

error: aborting due to 1 previous error

51 changes: 51 additions & 0 deletions tests/ui/async-await/pin-sugar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//@ check-pass

#![feature(pin_ergonomics)]
#![allow(dead_code, incomplete_features)]

// Makes sure we can handle `&pin mut T` and `&pin const T` as sugar for `Pin<&mut T>` and
// `Pin<&T>`.

use std::pin::Pin;

struct Foo;

impl Foo {
fn baz(self: &pin mut Self) {
}

fn baz_const(self: &pin const Self) {
}

fn baz_lt<'a>(self: &'a pin mut Self) {
}

fn baz_const_lt(self: &'_ pin const Self) {
}
}

fn foo(_: &pin mut Foo) {
}

fn foo_const(x: &pin const Foo) {
}

fn bar(x: &pin mut Foo) {
foo(x);
foo(x); // for this to work we need to automatically reborrow,
// as if the user had written `foo(x.as_mut())`.

Foo::baz(x);
Foo::baz(x);

// make sure we can reborrow &mut as &.
foo_const(x);
Foo::baz_const(x);

let x: &pin const _ = Pin::new(&Foo);

foo_const(x); // make sure reborrowing from & to & works.
foo_const(x);
}

fn main() {}
11 changes: 8 additions & 3 deletions tests/ui/feature-gates/feature-gate-pin_ergonomics.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![allow(dead_code, incomplete_features)]
#![allow(dead_code)]

use std::pin::Pin;

@@ -9,10 +9,13 @@ impl Foo {
}
}

fn foo(_: Pin<&mut Foo>) {
fn foo(x: Pin<&mut Foo>) {
let _y: &pin mut Foo = x; //~ ERROR pinned reference syntax is experimental
}

fn bar(mut x: Pin<&mut Foo>) {
fn foo_sugar(_: &pin mut Foo) {} //~ ERROR pinned reference syntax is experimental

fn bar(x: Pin<&mut Foo>) {
foo(x);
foo(x); //~ ERROR use of moved value: `x`
}
@@ -22,4 +25,6 @@ fn baz(mut x: Pin<&mut Foo>) {
x.foo(); //~ ERROR use of moved value: `x`
}

fn baz_sugar(_: &pin const Foo) {} //~ ERROR pinned reference syntax is experimental

fn main() {}
45 changes: 38 additions & 7 deletions tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,38 @@
error[E0658]: pinned reference syntax is experimental
--> $DIR/feature-gate-pin_ergonomics.rs:13:14
|
LL | let _y: &pin mut Foo = x;
| ^^^
|
= note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
= help: add `#![feature(pin_ergonomics)]` 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]: pinned reference syntax is experimental
--> $DIR/feature-gate-pin_ergonomics.rs:16:18
|
LL | fn foo_sugar(_: &pin mut Foo) {}
| ^^^
|
= note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
= help: add `#![feature(pin_ergonomics)]` 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]: pinned reference syntax is experimental
--> $DIR/feature-gate-pin_ergonomics.rs:28:18
|
LL | fn baz_sugar(_: &pin const Foo) {}
| ^^^
|
= note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
= help: add `#![feature(pin_ergonomics)]` 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[E0382]: use of moved value: `x`
--> $DIR/feature-gate-pin_ergonomics.rs:17:9
--> $DIR/feature-gate-pin_ergonomics.rs:20:9
|
LL | fn bar(mut x: Pin<&mut Foo>) {
| ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
LL | fn bar(x: Pin<&mut Foo>) {
| - move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
LL | foo(x);
| - value moved here
LL | foo(x);
@@ -11,13 +41,13 @@ LL | foo(x);
note: consider changing this parameter type in function `foo` to borrow instead if owning the value isn't necessary
--> $DIR/feature-gate-pin_ergonomics.rs:12:11
|
LL | fn foo(_: Pin<&mut Foo>) {
LL | fn foo(x: Pin<&mut Foo>) {
| --- ^^^^^^^^^^^^^ this parameter takes ownership of the value
| |
| in this function

error[E0382]: use of moved value: `x`
--> $DIR/feature-gate-pin_ergonomics.rs:22:5
--> $DIR/feature-gate-pin_ergonomics.rs:25:5
|
LL | fn baz(mut x: Pin<&mut Foo>) {
| ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
@@ -36,6 +66,7 @@ help: consider reborrowing the `Pin` instead of moving it
LL | x.as_mut().foo();
| +++++++++

error: aborting due to 2 previous errors
error: aborting due to 5 previous errors

For more information about this error, try `rustc --explain E0382`.
Some errors have detailed explanations: E0382, E0658.
For more information about an error, try `rustc --explain E0382`.