Skip to content

Commit 0feab53

Browse files
Add refine attribute
1 parent d190d97 commit 0feab53

File tree

11 files changed

+236
-0
lines changed

11 files changed

+236
-0
lines changed

compiler/rustc_feature/src/active.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,8 @@ declare_features! (
529529
(active, proc_macro_hygiene, "1.30.0", Some(54727), None),
530530
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
531531
(active, raw_ref_op, "1.41.0", Some(64490), None),
532+
/// Allows use of the `#![refine]` attribute, and checks items for accidental refinements.
533+
(incomplete, refine, "CURRENT_RUSTC_VERSION", Some(1), None),
532534
/// Allows using the `#[register_tool]` attribute.
533535
(active, register_tool, "1.41.0", Some(66079), None),
534536
/// Allows the `#[repr(i128)]` attribute for enums.

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,9 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
497497
experimental!(cfi_encoding)
498498
),
499499

500+
// RFC 3245
501+
gated!(refine, Normal, template!(Word), WarnFollowing, experimental!(refine)),
502+
500503
// ==========================================================================
501504
// Internal attributes: Stability, deprecation, and unsafe:
502505
// ==========================================================================

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3436,6 +3436,7 @@ declare_lint_pass! {
34363436
TYVAR_BEHIND_RAW_POINTER,
34373437
UNCONDITIONAL_PANIC,
34383438
UNCONDITIONAL_RECURSION,
3439+
UNDECLARED_REFINE,
34393440
UNDEFINED_NAKED_FUNCTION_ABI,
34403441
UNFULFILLED_LINT_EXPECTATIONS,
34413442
UNINHABITED_STATIC,
@@ -4422,6 +4423,14 @@ declare_lint! {
44224423
@feature_gate = sym::type_privacy_lints;
44234424
}
44244425

4426+
declare_lint! {
4427+
/// Refine
4428+
pub UNDECLARED_REFINE,
4429+
Warn,
4430+
"yeet",
4431+
@feature_gate = sym::refine;
4432+
}
4433+
44254434
declare_lint! {
44264435
/// The `unknown_diagnostic_attributes` lint detects unrecognized diagnostic attributes.
44274436
///

compiler/rustc_passes/messages.ftl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,23 @@ passes_attr_only_on_main =
5252
passes_attr_only_on_root_main =
5353
`{$attr}` attribute can only be used on root `fn main()`
5454
55+
passes_bad_refine_attr_assoc_const =
56+
associated consts cannot be refined
57+
.label = this associated const
58+
59+
passes_bad_refine_attr_inherent_impl =
60+
`#[refine]` attribute cannot be put on an item in an inherent impl
61+
.note = the attribute is useless because the item does not refine anything
62+
.label = this impl item
63+
64+
passes_bad_refine_attr_other_item =
65+
`#[refine]` attribute must be put on an associated function or type in a trait implementation
66+
.label = this item
67+
passes_bad_refine_attr_trait =
68+
`#[refine]` attribute cannot be put on an item in a trait
69+
.note = the attribute is useless because the item does not refine anything
70+
.label = this trait item
71+
5572
passes_both_ffi_const_and_pure =
5673
`#[ffi_const]` function cannot be `#[ffi_pure]`
5774

compiler/rustc_passes/src/check_attr.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ impl CheckAttrVisitor<'_> {
183183
| sym::rustc_allowed_through_unstable_modules
184184
| sym::rustc_promotable => self.check_stability_promotable(&attr, span, target),
185185
sym::link_ordinal => self.check_link_ordinal(&attr, span, target),
186+
sym::refine => self.check_refine(&attr, span, target, hir_id),
186187
sym::rustc_confusables => self.check_confusables(&attr, target),
187188
_ => true,
188189
};
@@ -2304,6 +2305,37 @@ impl CheckAttrVisitor<'_> {
23042305
self.abort.set(true);
23052306
}
23062307
}
2308+
2309+
fn check_refine(&self, attr: &Attribute, span: Span, target: Target, hir_id: HirId) -> bool {
2310+
let attr_span = attr.span;
2311+
match target {
2312+
Target::Method(_) | Target::AssocTy => {
2313+
let parent_def_id = self.tcx.hir().get_parent_item(hir_id).def_id;
2314+
match self.tcx.hir().expect_item(parent_def_id).kind {
2315+
hir::ItemKind::Impl(impl_) if impl_.of_trait.is_some() => true,
2316+
hir::ItemKind::Impl(..) => {
2317+
self.tcx
2318+
.sess
2319+
.emit_err(errors::BadRefineAttr::InherentImpl { span, attr_span });
2320+
false
2321+
}
2322+
hir::ItemKind::Trait(..) => {
2323+
self.tcx.sess.emit_err(errors::BadRefineAttr::Trait { span, attr_span });
2324+
false
2325+
}
2326+
_ => unreachable!("only expect assoc ty and method on trait/impl"),
2327+
}
2328+
}
2329+
Target::AssocConst => {
2330+
self.tcx.sess.emit_err(errors::BadRefineAttr::AssocConst { span, attr_span });
2331+
false
2332+
}
2333+
_ => {
2334+
self.tcx.sess.emit_err(errors::BadRefineAttr::OtherItem { span, attr_span });
2335+
false
2336+
}
2337+
}
2338+
}
23072339
}
23082340

23092341
impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {

compiler/rustc_passes/src/errors.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,3 +1757,37 @@ pub struct AttrCrateLevelOnlySugg {
17571757
#[primary_span]
17581758
pub attr: Span,
17591759
}
1760+
1761+
#[derive(Diagnostic)]
1762+
pub enum BadRefineAttr {
1763+
#[diag(passes_bad_refine_attr_inherent_impl)]
1764+
#[note]
1765+
InherentImpl {
1766+
#[primary_span]
1767+
attr_span: Span,
1768+
#[label]
1769+
span: Span,
1770+
},
1771+
#[diag(passes_bad_refine_attr_trait)]
1772+
#[note]
1773+
Trait {
1774+
#[primary_span]
1775+
attr_span: Span,
1776+
#[label]
1777+
span: Span,
1778+
},
1779+
#[diag(passes_bad_refine_attr_assoc_const)]
1780+
AssocConst {
1781+
#[primary_span]
1782+
attr_span: Span,
1783+
#[label]
1784+
span: Span,
1785+
},
1786+
#[diag(passes_bad_refine_attr_other_item)]
1787+
OtherItem {
1788+
#[primary_span]
1789+
attr_span: Span,
1790+
#[label]
1791+
span: Span,
1792+
},
1793+
}

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,7 @@ symbols! {
12011201
reexport_test_harness_main,
12021202
ref_unwind_safe_trait,
12031203
reference,
1204+
refine,
12041205
reflect,
12051206
reg,
12061207
reg16,
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
trait Foo {
2+
fn assoc();
3+
}
4+
5+
impl Foo for () {
6+
#[refine]
7+
//~^ ERROR the `#[refine]` attribute is an experimental feature
8+
fn assoc() {}
9+
}
10+
11+
fn main() {}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0658]: the `#[refine]` attribute is an experimental feature
2+
--> $DIR/feature-gate-refine.rs:6:5
3+
|
4+
LL | #[refine]
5+
| ^^^^^^^^^
6+
|
7+
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
8+
= help: add `#![feature(refine)]` to the crate attributes to enable
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0658`.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#![feature(refine)]
2+
3+
trait Foo {
4+
#[refine]
5+
//~^ ERROR `#[refine]` attribute cannot be put on an item in a trait
6+
fn assoc();
7+
8+
#[refine]
9+
//~^ ERROR `#[refine]` attribute cannot be put on an item in a trait
10+
type Assoc;
11+
12+
#[refine]
13+
//~^ ERROR associated consts cannot be refined
14+
const N: u32;
15+
}
16+
17+
struct W;
18+
impl W {
19+
#[refine]
20+
//~^ ERROR `#[refine]` attribute cannot be put on an item in an inherent impl
21+
fn assoc() {}
22+
23+
#[refine]
24+
//~^ ERROR associated consts cannot be refined
25+
const M: u32 = 1;
26+
}
27+
28+
impl Foo for W {
29+
#[refine]
30+
//~^ ERROR associated consts cannot be refined
31+
const N: u32 = 1;
32+
33+
#[refine]
34+
fn assoc() {} // Ok
35+
36+
#[refine]
37+
type Assoc = (); // Ok
38+
}
39+
40+
#[refine]
41+
//~^ ERROR `#[refine]` attribute must be put on an associated function or type in a trait implementation
42+
fn foo() {}
43+
44+
fn main() {}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
error: `#[refine]` attribute must be put on an associated function or type in a trait implementation
2+
--> $DIR/attr.rs:40:1
3+
|
4+
LL | #[refine]
5+
| ^^^^^^^^^
6+
LL |
7+
LL | fn foo() {}
8+
| ----------- this item
9+
10+
error: `#[refine]` attribute cannot be put on an item in a trait
11+
--> $DIR/attr.rs:4:5
12+
|
13+
LL | #[refine]
14+
| ^^^^^^^^^
15+
LL |
16+
LL | fn assoc();
17+
| ----------- this trait item
18+
|
19+
= note: the attribute is useless because the item does not refine anything
20+
21+
error: `#[refine]` attribute cannot be put on an item in a trait
22+
--> $DIR/attr.rs:8:5
23+
|
24+
LL | #[refine]
25+
| ^^^^^^^^^
26+
LL |
27+
LL | type Assoc;
28+
| ----------- this trait item
29+
|
30+
= note: the attribute is useless because the item does not refine anything
31+
32+
error: associated consts cannot be refined
33+
--> $DIR/attr.rs:12:5
34+
|
35+
LL | #[refine]
36+
| ^^^^^^^^^
37+
LL |
38+
LL | const N: u32;
39+
| ------------- this associated const
40+
41+
error: `#[refine]` attribute cannot be put on an item in an inherent impl
42+
--> $DIR/attr.rs:19:5
43+
|
44+
LL | #[refine]
45+
| ^^^^^^^^^
46+
LL |
47+
LL | fn assoc() {}
48+
| ------------- this impl item
49+
|
50+
= note: the attribute is useless because the item does not refine anything
51+
52+
error: associated consts cannot be refined
53+
--> $DIR/attr.rs:23:5
54+
|
55+
LL | #[refine]
56+
| ^^^^^^^^^
57+
LL |
58+
LL | const M: u32 = 1;
59+
| ----------------- this associated const
60+
61+
error: associated consts cannot be refined
62+
--> $DIR/attr.rs:29:5
63+
|
64+
LL | #[refine]
65+
| ^^^^^^^^^
66+
LL |
67+
LL | const N: u32 = 1;
68+
| ----------------- this associated const
69+
70+
error: aborting due to 7 previous errors
71+

0 commit comments

Comments
 (0)