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

Missing help when trying to enable stabilized library feature on stable #88802

Closed
jruderman opened this issue Sep 9, 2021 · 27 comments
Closed
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-stability Area: `#[stable]`, `#[unstable]` etc. E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jruderman
Copy link
Contributor

jruderman commented Sep 9, 2021

Given the following code:

#![feature(discriminant_value)]
fn main() {
    let y = Some(1);
    println!("{:?}", std::mem::discriminant(&y));
}

The current output is:

error[E0554]: `#![feature]` may not be used on the stable release channel
 --> src/main.rs:1:1
  |
1 | #![feature(discriminant_value)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Ideally the output should look like:

error: ...
help: the feature `discriminant_value` has been stable since 1.21.0 and no longer requires an attribute to enable

(or it could be downgraded from error to warning)

#83722 fixed this for #![feature(min_const_generics)] but not for #![feature(discriminant_value)], somehow

@jruderman jruderman added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 9, 2021
@jyn514
Copy link
Member

jyn514 commented Sep 10, 2021

Hmm, this might be because it's a library feature and not a language feature?

@jyn514
Copy link
Member

jyn514 commented Sep 10, 2021

Mentoring instructions: include library features in this check:

let stable_since = lang_features

@jyn514 jyn514 added E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. A-stability Area: `#[stable]`, `#[unstable]` etc. labels Sep 10, 2021
@jyn514 jyn514 changed the title Missing help when trying to enable stabilized feature on stable Missing help when trying to enable stabilized library feature on stable Sep 10, 2021
@chansuke
Copy link
Contributor

@rustbot claim

@vishadGoyal
Copy link
Contributor

vishadGoyal commented Sep 11, 2021

Hi! I started working on this but didn't know I had to claim it first. It's my first time contributing to open source.
Anyway, so far I realized we need to combine these two Vectors instead of just using the declared_lang_features vector
the vectors

use of features

The remaining challenge is to combine two vectors with different data types.
Hope this helps @chansuke Best of luck!

@chansuke
Copy link
Contributor

@vishadGoyal I appreciate your great work. You should work on this :)

@chansuke chansuke removed their assignment Sep 11, 2021
@vishadGoyal
Copy link
Contributor

@rustbot claim

@vishadGoyal
Copy link
Contributor

Thanks a lot! I hope I didn't guilt you into doing this 😅 @chansuke

@vishadGoyal
Copy link
Contributor

Hi I'm having trouble with debugging my changes.

I have made changes in https://github.com/rust-lang/rust/blob/497ee321af3b8496eaccd7af7b437f18bab81abf/compiler/rustc_ast_passes/src/feature_gate.rs

Then I'm running
./x.py build
build/x86_64-unknown-linux-gnu/stage1/bin/rustc test.rs

I'm not seeing the effect of my changes when I do this.

Also is there a way to debug this by attaching breakpoints? I don't think my approach of using the binary is the correct way to do this.

@jyn514
Copy link
Member

jyn514 commented Sep 12, 2021

@vishadGoyal this bit of code only runs on the beta and stable channels. Try setting channel = "beta" in config.toml.

Also is there a way to debug this by attaching breakpoints? I don't think my approach of using the binary is the correct way to do this.

You can set debug = true in config.toml and then run it under gdb if you like.

@vishadGoyal
Copy link
Contributor

I tried this but it says unknown field channel

My config.toml

# Includes one of the default files in src/bootstrap/defaults
profile = "compiler"
changelog-seen = 2
channel = "beta"

The output on running ./x.py build

Updating only changed submodules
Submodules updated in 0.01 seconds
    Finished dev [unoptimized + debuginfo] target(s) in 0.09s
failed to parse TOML configuration 'config.toml': unknown field `channel`, expected one of `changelog-seen`, `build`, `install`, `llvm`, `rust`, `target`, `dist`, `profile` at line 1 column 1
Build completed unsuccessfully in 0:00:00

@jyn514
Copy link
Member

jyn514 commented Sep 12, 2021

@vishadGoyal it needs to be under one of the tables (I think maybe rust?). Look at config.toml.example, it will give an example.

@vishadGoyal
Copy link
Contributor

vishadGoyal commented Sep 12, 2021

Thanks
It should be under [rust]. I think the config.toml.example can be improved by adding indentation.

@jyn514
Copy link
Member

jyn514 commented Sep 12, 2021

Feel free to make a PR adding it :)

@vishadGoyal
Copy link
Contributor

I'm facing a problem. declared_lang_features obtained from the Session object have a since property but not the declared_lib_features.

let lang_features = &sess.features_untracked().declared_lang_features;

pub declared_lang_features: Vec<(Symbol, Span, Option<Symbol>)>,

pub declared_lib_features: Vec<(Symbol, Span)>,

I searched the code and found that a list of all lib features can be queried from the TyCtxt object like in

let local_defined_features = tcx.lib_features().to_vec();

and

check_features(&mut remaining_lib_features, tcx.defined_lib_features(cnum));

Is there a way to get the same data from the Session object? I couldn't find it.

@jyn514
Copy link
Member

jyn514 commented Sep 12, 2021

Is there a way to get the same data from the Session object? I couldn't find it.

@vishadGoyal I think it would be reasonable to add it to declared_lib_features :) the features are created in

features.declared_lib_features.push((name, mi.span()));

@vishadGoyal
Copy link
Contributor

The implementation there is to access the declared features in https://github.com/rust-lang/rust/tree/c7dbe7a830100c70d59994fd940bf75bb6e39b39/compiler/rustc_feature/src

and if the feature name doesn't match with any of these, it is assumed to be a lib feature, the stable since data is still not there.

However, I found the data in

#[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]

This is accessed via the HIR here,

tcx.hir().walk_attributes(&mut collector);

and exposed via this query

query get_lib_features(_: ()) -> LibFeatures {

I have two questions:

  1. Can this query only be run through a type context object (TyCtxt) or also through the Session object?
  2. Is there a way to excess the attributes declared in the interface in library/core/src/intrinsics.rs and other such files without going via the HIR?

@jyn514
Copy link
Member

jyn514 commented Sep 13, 2021

@vishadGoyal yes, queries can only be run through a TyCtxt. No, I wouldn't expect so, there's the ast::Attributes but you need more than just a Session to access them.

What's wrong with recording the since field in Session like I suggested?

@vishadGoyal
Copy link
Contributor

vishadGoyal commented Sep 13, 2021

The data is not already present where the declared_lib_features is currently being built.
Its present in library/core/src/intrinsics.rs
I'm not sure how to access it from where you mentioned.

@jyn514
Copy link
Member

jyn514 commented Sep 13, 2021

@vishadGoyal it should be in the attribute you're currently looking at - see how it's done in

if let Some(stab_attr) = stab_attrs.iter().find(|stab_attr| attr.has_name(**stab_attr)) {

The language features are hard-coded into the compiler, but that doesn't mean the library features aren't available, they just have to be determined at runtime.

@vishadGoyal
Copy link
Contributor

I logged the attribute being looked at

[Attribute { kind: Normal(AttrItem { path: Path { span: ../reproduce-88802.rs:1:4: 1:11 (#0), segments: [PathSegment { ident: feature#0, id: NodeId(4294967040), args: None }], tokens: None }, args: Delimited(DelimSpan { open: ../reproduce-88802.rs:1:11: 1:12 (#0), close: ../reproduce-88802.rs:1:30: 1:31 (#0) }, Parenthemetasis, TokenStream([(Token(Token { kind: Ident("discriminant_value", false), span: ../reproduce-88802.rs:1:12: 1:30 (#0) }), Alone)])), tokens: None }, Some(LazyTokenStream(AttrAnnotatedTokenStream([(Token(Token { kind: Pound, span: ../reproduce-88802.rs:1:1: 1:2 (#0) }), Joint), (Token(Token { kind: Not, span: ../reproduce-88802.rs:1:2: 1:3 (#0) }), Alone), (Delimited(DelimSpan { open: ../reproduce-88802.rs:1:3: 1:4 (#0), close: ../reproduce-88802.rs:1:31: 1:32 (#0) }, Bracket, AttrAnnotatedTokenStream([(Token(Token { kind: Ident("feature", false), span: ../reproduce-88802.rs:1:4: 1:11 (#0) }), Alone), (Delimited(DelimSpan { open: ../reproduce-88802.rs:1:11: 1:12 (#0), close: ../reproduce-88802.rs:1:30: 1:31 (#0) }, Paren, AttrAnnotatedTokenStream([(Token(Token { kind: Ident("discriminant_value", false), span: ../reproduce-88802.rs:1:12: 1:30 (#0) }), Alone)])), Alone)])), Alone)])))), id: AttrId(0), style: Inner, span: ../reproduce-88802.rs:1:1: 1:32 (#0) }]

I couldn't find any stability attribute in it or it's meta. The output when I printed the meta of this attr was

Some(MetaItem { path: Path { span: ../reproduce-88802.rs:1:4: 1:11 (#0), segments: [PathSegment { ident: feature#0, id: NodeId(4294967040), args: None }], tokens: None }, kind: List([MetaItem(MetaItem { path: Path { span: ../reproduce-88802.rs:1:12: 1:30 (#0), segments: [PathSegment { ident: discriminant_value#0, id: NodeId(4294967040), args: None }], tokens: None }, kind: Word, span: ../reproduce-88802.rs:1:12: 1:30 (#0) })]), span: ../reproduce-88802.rs:1:1: 1:32 (#0) })

@jyn514
Copy link
Member

jyn514 commented Sep 13, 2021

@vishadGoyal you're looking at the #[feature(...)] attribute. You want to look at the #[stable(...)] attribute.

Hmm, this may be tricky to do in parsing, since it's in another crate - I wonder if we could delay checking library features until later in the compiler, maybe to the pass where it checks if the feature is already stable? I remember @Mark-Simulacrum saying features were checked early to avoid stabilizing syntax by accident, but that shouldn't be an issue for library features: https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Why.20are.20feature.20gates.20checked.20during.20parsing.3F

@jyn514 jyn514 added E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. and removed E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. labels Sep 13, 2021
@vishadGoyal
Copy link
Contributor

I'm new to this so can you explain why the treatment can be different for lang features and lib features?

@jyn514
Copy link
Member

jyn514 commented Sep 14, 2021

Library features can't affect the syntax passed to proc macros; language features can.

@vishadGoyal
Copy link
Contributor

So, what should be the ideal behavior in this scenario?
If #![feature] is used with only lib features and not with a language feature, should the compiler still throw an error or just a warning for unnecessary_stable_feature_lint?
Or should we always throw an error if #![feature] is used in beta or stable channels?

@jyn514
Copy link
Member

jyn514 commented Sep 16, 2021

@vishadGoyal you should still give a hard error, but it should be later in the compiler after the TyCtxt has been constructed, not during parsing.

@vishadGoyal
Copy link
Contributor

I've made the suggested changes. #89012

GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Sep 17, 2021
Suggest removing `#![feature]` for library features that have been stabilized

Issue: rust-lang#88802
Delayed the check if #![feature] has been used to enable lib features in a non-nightly build to occur after TyCtxt has been constructed.
@jyn514
Copy link
Member

jyn514 commented Sep 23, 2021

Fixed in #89012.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-stability Area: `#[stable]`, `#[unstable]` etc. E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants