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 11 pull requests #126914

Merged
merged 28 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3af6242
rustc_codegen_ssa: Remove unused ModuleConfig::inline_threshold
Enselic May 4, 2024
651ff64
Fix typo in `-Cno-stack-check` deprecation warning
Enselic Jun 14, 2024
f5f067b
Deprecate no-op codegen option `-Cinline-threshold=...`
Enselic May 4, 2024
d630f5d
Show notice about "never used" for enum
long-long-float Apr 28, 2024
3f2f843
Ensure we don't accidentally succeed when we want to report an error
oli-obk Jun 13, 2024
f1be59f
SmartPointer derive-macro
dingxiangfei2009 May 26, 2024
b5dfeba
coverage: Forbid multiple `#[coverage(..)]` attributes
Zalathar Jun 19, 2024
a000fa8
coverage: Tighten validation of `#[coverage(off)]` and `#[coverage(on)]`
Zalathar Jun 20, 2024
b7c057c
coverage: Always error on `#[coverage(..)]` in unexpected places
Zalathar Jun 19, 2024
1852141
coverage: Bless coverage attribute tests
Zalathar Jun 20, 2024
ba5ec1f
Suggest inline const blocks for array initialization
GrigorenkoPV Jun 24, 2024
8ffb5f9
compiletest: make the crash test error message abit more informative
matthiaskrgr Jun 13, 2024
1c4d0ce
Separate the lifetimes of the `BorrowckInferCtxt` from the other borr…
oli-obk Jun 20, 2024
8fc6b3d
Separate the mir body lifetime from the other lifetimes
oli-obk Jun 24, 2024
84474a2
Small fixme in core now that NonZero is generic
GrigorenkoPV Jun 24, 2024
45261ff
add @kobzol to bootstrap team for triagebot
onur-ozkan Jun 24, 2024
13fca73
Replace `MaybeUninit::uninit_array()` with array repeat expression.
kpreid May 13, 2024
00e5f58
Rollup merge of #124460 - long-long-float:show-notice-about-enum-with…
compiler-errors Jun 24, 2024
faa28be
Rollup merge of #124712 - Enselic:deprecate-inline-threshold, r=pnkfelix
compiler-errors Jun 24, 2024
c77dc28
Rollup merge of #125082 - kpreid:const-uninit, r=dtolnay
compiler-errors Jun 24, 2024
ed460d2
Rollup merge of #125575 - dingxiangfei2009:derive-smart-ptr, r=davidtwco
compiler-errors Jun 24, 2024
46e4398
Rollup merge of #126413 - matthiaskrgr:crshmsg, r=oli-obk
compiler-errors Jun 24, 2024
49bdf46
Rollup merge of #126673 - oli-obk:dont_rely_on_err_reporting, r=compi…
compiler-errors Jun 24, 2024
9ce2a07
Rollup merge of #126682 - Zalathar:coverage-attr, r=lcnr
compiler-errors Jun 24, 2024
a7721a0
Rollup merge of #126899 - GrigorenkoPV:suggest-const-block, r=davidtwco
compiler-errors Jun 24, 2024
85eb835
Rollup merge of #126904 - GrigorenkoPV:nonzero-fixme, r=joboet
compiler-errors Jun 24, 2024
59c258f
Rollup merge of #126909 - onur-ozkan:add-kobzol, r=matthiaskrgr
compiler-errors Jun 24, 2024
16bd6e2
Rollup merge of #126911 - oli-obk:do_not_count_errors, r=compiler-errors
compiler-errors Jun 24, 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
Prev Previous commit
Next Next commit
SmartPointer derive-macro
Co-authored-by: Wedson Almeida Filho <walmeida@microsoft.com>
  • Loading branch information
dingxiangfei2009 and wedsonaf committed Jun 23, 2024
commit f1be59fa72b06c4a28acc59a0f0dff1484db0778
1 change: 1 addition & 0 deletions compiler/rustc_builtin_macros/src/deriving/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub(crate) mod decodable;
pub(crate) mod default;
pub(crate) mod encodable;
pub(crate) mod hash;
pub(crate) mod smart_ptr;

#[path = "cmp/eq.rs"]
pub(crate) mod eq;
Expand Down
140 changes: 140 additions & 0 deletions compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
use std::mem::swap;

use ast::HasAttrs;
use rustc_ast::{
self as ast, GenericArg, GenericBound, GenericParamKind, ItemKind, MetaItem,
TraitBoundModifiers,
};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use smallvec::{smallvec, SmallVec};
use thin_vec::{thin_vec, ThinVec};

macro_rules! path {
($span:expr, $($part:ident)::*) => { vec![$(Ident::new(sym::$part, $span),)*] }
}

pub fn expand_deriving_smart_ptr(
cx: &ExtCtxt<'_>,
span: Span,
_mitem: &MetaItem,
item: &Annotatable,
push: &mut dyn FnMut(Annotatable),
_is_const: bool,
) {
let (name_ident, generics) = if let Annotatable::Item(aitem) = item
&& let ItemKind::Struct(_, g) = &aitem.kind
{
(aitem.ident, g)
} else {
cx.dcx().struct_span_err(span, "`SmartPointer` can only be derived on `struct`s").emit();
return;
};

// Convert generic parameters (from the struct) into generic args.
let mut pointee_param = None;
let mut multiple_pointee_diag: SmallVec<[_; 2]> = smallvec![];
let self_params = generics
.params
.iter()
.enumerate()
.map(|(idx, p)| match p.kind {
GenericParamKind::Lifetime => GenericArg::Lifetime(cx.lifetime(p.span(), p.ident)),
GenericParamKind::Type { .. } => {
if p.attrs().iter().any(|attr| attr.has_name(sym::pointee)) {
if pointee_param.is_some() {
multiple_pointee_diag.push(cx.dcx().struct_span_err(
p.span(),
"`SmartPointer` can only admit one type as pointee",
));
} else {
pointee_param = Some(idx);
}
}
GenericArg::Type(cx.ty_ident(p.span(), p.ident))
}
GenericParamKind::Const { .. } => GenericArg::Const(cx.const_ident(p.span(), p.ident)),
})
.collect::<Vec<_>>();
let Some(pointee_param_idx) = pointee_param else {
cx.dcx().struct_span_err(
span,
"At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits",
).emit();
return;
};
if !multiple_pointee_diag.is_empty() {
for diag in multiple_pointee_diag {
diag.emit();
}
return;
}

// Create the type of `self`.
let path = cx.path_all(span, false, vec![name_ident], self_params.clone());
let self_type = cx.ty_path(path);

// Declare helper function that adds implementation blocks.
// FIXME(dingxiangfei2009): Investigate the set of attributes on target struct to be propagated to impls
let attrs = thin_vec![cx.attr_word(sym::automatically_derived, span),];
let mut add_impl_block = |generics, trait_symbol, trait_args| {
let mut parts = path!(span, core::ops);
parts.push(Ident::new(trait_symbol, span));
let trait_path = cx.path_all(span, true, parts, trait_args);
let trait_ref = cx.trait_ref(trait_path);
let item = cx.item(
span,
Ident::empty(),
attrs.clone(),
ast::ItemKind::Impl(Box::new(ast::Impl {
safety: ast::Safety::Default,
polarity: ast::ImplPolarity::Positive,
defaultness: ast::Defaultness::Final,
constness: ast::Const::No,
generics,
of_trait: Some(trait_ref),
self_ty: self_type.clone(),
items: ThinVec::new(),
})),
);
push(Annotatable::Item(item));
};

// Create unsized `self`, that is, one where the `#[pointee]` type arg is replaced with `__S`. For
// example, instead of `MyType<'a, T>`, it will be `MyType<'a, __S>`.
let s_ty = cx.ty_ident(span, Ident::new(sym::__S, span));
let mut alt_self_params = self_params;
alt_self_params[pointee_param_idx] = GenericArg::Type(s_ty.clone());
let alt_self_type = cx.ty_path(cx.path_all(span, false, vec![name_ident], alt_self_params));

// Find the `#[pointee]` parameter and add an `Unsize<__S>` bound to it.
let mut impl_generics = generics.clone();
{
let p = &mut impl_generics.params[pointee_param_idx];
let arg = GenericArg::Type(s_ty.clone());
let unsize = cx.path_all(span, true, path!(span, core::marker::Unsize), vec![arg]);
p.bounds.push(cx.trait_bound(unsize, false));
let mut attrs = thin_vec![];
swap(&mut p.attrs, &mut attrs);
p.attrs = attrs.into_iter().filter(|attr| !attr.has_name(sym::pointee)).collect();
}

// Add the `__S: ?Sized` extra parameter to the impl block.
let sized = cx.path_global(span, path!(span, core::marker::Sized));
let bound = GenericBound::Trait(
cx.poly_trait_ref(span, sized),
TraitBoundModifiers {
polarity: ast::BoundPolarity::Maybe(span),
constness: ast::BoundConstness::Never,
asyncness: ast::BoundAsyncness::Normal,
},
);
let extra_param = cx.typaram(span, Ident::new(sym::__S, span), vec![bound], None);
impl_generics.params.push(extra_param);

// Add the impl blocks for `DispatchFromDyn` and `CoerceUnsized`.
let gen_args = vec![GenericArg::Type(alt_self_type.clone())];
add_impl_block(impl_generics.clone(), sym::DispatchFromDyn, gen_args.clone());
add_impl_block(impl_generics.clone(), sym::CoerceUnsized, gen_args.clone());
}
1 change: 1 addition & 0 deletions compiler/rustc_builtin_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
PartialOrd: partial_ord::expand_deriving_partial_ord,
RustcDecodable: decodable::expand_deriving_rustc_decodable,
RustcEncodable: encodable::expand_deriving_rustc_encodable,
SmartPointer: smart_ptr::expand_deriving_smart_ptr,
}

let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
EncodeCrossCrate::No, coroutines, experimental!(coroutines)
),

// `#[pointee]` attribute to designate the pointee type in SmartPointer derive-macro
gated!(
pointee, Normal, template!(Word), ErrorFollowing,
EncodeCrossCrate::No, derive_smart_pointer, experimental!(pointee)
),

// ==========================================================================
// Internal attributes: Stability, deprecation, and unsafe:
// ==========================================================================
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,8 @@ declare_features! (
(unstable, deprecated_suggestion, "1.61.0", Some(94785)),
/// Allows deref patterns.
(incomplete, deref_patterns, "1.79.0", Some(87121)),
/// Allows deriving `SmartPointer` traits
(unstable, derive_smart_pointer, "1.79.0", Some(123430)),
/// Controls errors in trait implementations.
(unstable, do_not_recommend, "1.67.0", Some(51992)),
/// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ symbols! {
Center,
Cleanup,
Clone,
CoerceUnsized,
Command,
ConstParamTy,
Context,
Expand All @@ -189,6 +190,7 @@ symbols! {
DiagMessage,
Diagnostic,
DirBuilder,
DispatchFromDyn,
Display,
DoubleEndedIterator,
Duration,
Expand Down Expand Up @@ -299,8 +301,10 @@ symbols! {
Saturating,
Send,
SeqCst,
Sized,
SliceIndex,
SliceIter,
SmartPointer,
Some,
SpanCtxt,
String,
Expand All @@ -323,6 +327,7 @@ symbols! {
TyCtxt,
TyKind,
Unknown,
Unsize,
Upvars,
Vec,
VecDeque,
Expand Down Expand Up @@ -707,6 +712,7 @@ symbols! {
derive,
derive_const,
derive_default_enum,
derive_smart_pointer,
destruct,
destructuring_assignment,
diagnostic,
Expand Down Expand Up @@ -1315,6 +1321,7 @@ symbols! {
on,
on_unimplemented,
opaque,
ops,
opt_out_copy,
optimize,
optimize_attribute,
Expand Down Expand Up @@ -1389,6 +1396,7 @@ symbols! {
plugin,
plugin_registrar,
plugins,
pointee,
pointee_trait,
pointer,
pointer_like,
Expand Down
9 changes: 9 additions & 0 deletions library/core/src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1018,3 +1018,12 @@ pub trait FnPtr: Copy + Clone {
#[lang = "fn_ptr_addr"]
fn addr(self) -> *const ();
}

/// Derive macro generating impls of traits related to smart pointers.
#[cfg(not(bootstrap))]
#[rustc_builtin_macro]
#[allow_internal_unstable(dispatch_from_dyn, coerce_unsized, unsize)]
#[unstable(feature = "derive_smart_pointer", issue = "123430")]
pub macro SmartPointer($item:item) {
/* compiler built-in */
}
55 changes: 55 additions & 0 deletions tests/ui/deriving/deriving-smart-pointer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//@ run-pass
#![feature(derive_smart_pointer, arbitrary_self_types)]

use std::marker::SmartPointer;

#[derive(SmartPointer)]
struct MyPointer<'a, #[pointee] T: ?Sized> {
ptr: &'a T,
}

impl<T: ?Sized> Copy for MyPointer<'_, T> {}
impl<T: ?Sized> Clone for MyPointer<'_, T> {
fn clone(&self) -> Self {
Self { ptr: self.ptr }
}
}

impl<'a, T: ?Sized> core::ops::Deref for MyPointer<'a, T> {
type Target = T;
fn deref(&self) -> &'a T {
self.ptr
}
}

struct MyValue(u32);
impl MyValue {
fn through_pointer(self: MyPointer<'_, Self>) -> u32 {
self.ptr.0
}
}

trait MyTrait {
fn through_trait(&self) -> u32;
fn through_trait_and_pointer(self: MyPointer<'_, Self>) -> u32;
}

impl MyTrait for MyValue {
fn through_trait(&self) -> u32 {
self.0
}

fn through_trait_and_pointer(self: MyPointer<'_, Self>) -> u32 {
self.ptr.0
}
}

pub fn main() {
let v = MyValue(10);
let ptr = MyPointer { ptr: &v };
assert_eq!(v.0, ptr.through_pointer());
assert_eq!(v.0, ptr.through_pointer());
let dptr = ptr as MyPointer<dyn MyTrait>;
assert_eq!(v.0, dptr.through_trait());
assert_eq!(v.0, dptr.through_trait_and_pointer());
}
9 changes: 9 additions & 0 deletions tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use std::marker::SmartPointer; //~ ERROR use of unstable library feature 'derive_smart_pointer'

#[derive(SmartPointer)] //~ ERROR use of unstable library feature 'derive_smart_pointer'
struct MyPointer<'a, #[pointee] T: ?Sized> {
//~^ ERROR the `#[pointee]` attribute is an experimental feature
ptr: &'a T,
}

fn main() {}
33 changes: 33 additions & 0 deletions tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
error[E0658]: use of unstable library feature 'derive_smart_pointer'
--> $DIR/feature-gate-derive-smart-pointer.rs:3:10
|
LL | #[derive(SmartPointer)]
| ^^^^^^^^^^^^
|
= note: see issue #123430 <https://github.com/rust-lang/rust/issues/123430> for more information
= help: add `#![feature(derive_smart_pointer)]` 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]: the `#[pointee]` attribute is an experimental feature
--> $DIR/feature-gate-derive-smart-pointer.rs:4:22
|
LL | struct MyPointer<'a, #[pointee] T: ?Sized> {
| ^^^^^^^^^^
|
= note: see issue #123430 <https://github.com/rust-lang/rust/issues/123430> for more information
= help: add `#![feature(derive_smart_pointer)]` 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]: use of unstable library feature 'derive_smart_pointer'
--> $DIR/feature-gate-derive-smart-pointer.rs:1:5
|
LL | use std::marker::SmartPointer;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #123430 <https://github.com/rust-lang/rust/issues/123430> for more information
= help: add `#![feature(derive_smart_pointer)]` 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: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0658`.
Loading