mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Auto merge of #71828 - Dylan-DPC:rollup-qf5h2w5, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #71165 (`slice::fill`: use `T` instead of generic arg) - #71314 (Implement RFC 2523, `#[cfg(version(..))]`) - #71542 (Implement `confusable_idents` lint.) - #71806 (typo) - #71813 (Decode qualifs for associated const defaults) Failed merges: r? @ghost
This commit is contained in:
commit
d626e4dadc
82
Cargo.lock
82
Cargo.lock
@ -74,7 +74,7 @@ name = "arena"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rustc_data_structures",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -492,7 +492,7 @@ dependencies = [
|
||||
"regex-syntax",
|
||||
"semver",
|
||||
"serde",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
"toml",
|
||||
"unicode-normalization",
|
||||
"url 2.1.0",
|
||||
@ -2428,7 +2428,7 @@ dependencies = [
|
||||
"cloudabi",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
@ -3151,7 +3151,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81dfcfbb0ddfd533abf8c076e3b49d1e5042d1962526a12ce2c66d514b24cca3"
|
||||
dependencies = [
|
||||
"rustc-ap-rustc_data_structures",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3174,7 +3174,7 @@ dependencies = [
|
||||
"rustc-ap-rustc_span",
|
||||
"rustc-ap-serialize",
|
||||
"scoped-tls",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3223,7 +3223,7 @@ dependencies = [
|
||||
"rustc-ap-rustc_session",
|
||||
"rustc-ap-rustc_span",
|
||||
"rustc-ap-serialize",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3249,7 +3249,7 @@ dependencies = [
|
||||
"rustc-hash",
|
||||
"rustc-rayon",
|
||||
"rustc-rayon-core",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
"stable_deref_trait",
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
@ -3291,7 +3291,7 @@ dependencies = [
|
||||
"rustc-ap-rustc_session",
|
||||
"rustc-ap-rustc_span",
|
||||
"rustc-ap-serialize",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3318,7 +3318,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32220c3e6cdf226f38e4474b747dca15f3106bb680c74f10b299af3f6cdb1663"
|
||||
dependencies = [
|
||||
"rustc-ap-serialize",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3358,7 +3358,7 @@ dependencies = [
|
||||
"rustc-ap-rustc_lexer",
|
||||
"rustc-ap-rustc_session",
|
||||
"rustc-ap-rustc_span",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
@ -3423,7 +3423,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "756e8f526ec7906e132188bf25e3c10a6ee42ab77294ecb3b3602647f0508eef"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3507,7 +3507,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"smallvec 0.6.10",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
"syn 0.15.35",
|
||||
"url 2.1.0",
|
||||
"winapi 0.3.8",
|
||||
@ -3518,7 +3518,7 @@ name = "rustc_apfloat"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3533,7 +3533,7 @@ dependencies = [
|
||||
"rustc_span",
|
||||
"scoped-tls",
|
||||
"serialize",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3551,7 +3551,7 @@ dependencies = [
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3593,6 +3593,7 @@ dependencies = [
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"serialize",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3612,7 +3613,7 @@ dependencies = [
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3641,7 +3642,7 @@ dependencies = [
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"serialize",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3694,7 +3695,7 @@ dependencies = [
|
||||
"rustc-rayon-core",
|
||||
"rustc_index",
|
||||
"serialize",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
"stable_deref_trait",
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
@ -3768,7 +3769,7 @@ dependencies = [
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"serialize",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3797,7 +3798,7 @@ dependencies = [
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"serialize",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3833,7 +3834,7 @@ name = "rustc_index"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"serialize",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3853,7 +3854,7 @@ dependencies = [
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"serialize",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3895,7 +3896,7 @@ dependencies = [
|
||||
"rustc_ty",
|
||||
"rustc_typeck",
|
||||
"serialize",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
"tempfile",
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
@ -3968,7 +3969,7 @@ dependencies = [
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"serialize",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
"stable_deref_trait",
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
@ -4000,7 +4001,7 @@ dependencies = [
|
||||
"rustc_target",
|
||||
"scoped-tls",
|
||||
"serialize",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4029,7 +4030,7 @@ dependencies = [
|
||||
"rustc_target",
|
||||
"rustc_trait_selection",
|
||||
"serialize",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4053,7 +4054,7 @@ dependencies = [
|
||||
"rustc_target",
|
||||
"rustc_trait_selection",
|
||||
"serialize",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4134,7 +4135,7 @@ dependencies = [
|
||||
"rustc_index",
|
||||
"rustc_span",
|
||||
"serialize",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4157,7 +4158,7 @@ dependencies = [
|
||||
"rustc_middle",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4272,7 +4273,7 @@ dependencies = [
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4287,7 +4288,7 @@ dependencies = [
|
||||
"rustc_middle",
|
||||
"rustc_span",
|
||||
"rustc_trait_selection",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4324,7 +4325,7 @@ dependencies = [
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"rustc_trait_selection",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4568,7 +4569,7 @@ name = "serialize"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4635,9 +4636,9 @@ checksum = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.0.0"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
|
||||
checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
@ -5359,11 +5360,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.11"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf"
|
||||
checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4"
|
||||
dependencies = [
|
||||
"smallvec 1.0.0",
|
||||
"smallvec 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5374,10 +5375,11 @@ checksum = "5b2c5c29e805da6817f5af6a627d65adb045cebf05cccd5a3493d6109454391c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-security"
|
||||
version = "0.0.2"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c49d35967fa037b881acc34ef717c38c4b5560eba10e3685271b3f530bb19634"
|
||||
checksum = "a5f9011bbed9c13372bc8df618b55a38138445199caf3b61d432c6859c36dee0"
|
||||
dependencies = [
|
||||
"unicode-normalization",
|
||||
"unicode-script",
|
||||
]
|
||||
|
||||
|
34
src/doc/unstable-book/src/language-features/cfg-version.md
Normal file
34
src/doc/unstable-book/src/language-features/cfg-version.md
Normal file
@ -0,0 +1,34 @@
|
||||
# `cfg_version`
|
||||
|
||||
The tracking issue for this feature is: [#64796]
|
||||
|
||||
[#64796]: https://github.com/rust-lang/rust/issues/64796
|
||||
|
||||
------------------------
|
||||
|
||||
The `cfg_version` feature makes it possible to execute different code
|
||||
depending on the compiler version.
|
||||
|
||||
## Examples
|
||||
|
||||
```rust
|
||||
#![feature(cfg_version)]
|
||||
|
||||
#[cfg(version("1.42"))]
|
||||
fn a() {
|
||||
// ...
|
||||
}
|
||||
|
||||
#[cfg(not(version("1.42")))]
|
||||
fn a() {
|
||||
// ...
|
||||
}
|
||||
|
||||
fn b() {
|
||||
if cfg!(version("1.42")) {
|
||||
// ...
|
||||
} else {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
@ -23,7 +23,6 @@
|
||||
// * The `raw` and `bytes` submodules.
|
||||
// * Boilerplate trait implementations.
|
||||
|
||||
use crate::borrow::Borrow;
|
||||
use crate::cmp;
|
||||
use crate::cmp::Ordering::{self, Equal, Greater, Less};
|
||||
use crate::fmt;
|
||||
@ -2157,14 +2156,16 @@ impl<T> [T] {
|
||||
/// assert_eq!(buf, vec![1; 10]);
|
||||
/// ```
|
||||
#[unstable(feature = "slice_fill", issue = "70758")]
|
||||
pub fn fill<V>(&mut self, value: V)
|
||||
pub fn fill(&mut self, value: T)
|
||||
where
|
||||
V: Borrow<T>,
|
||||
T: Clone,
|
||||
{
|
||||
let value = value.borrow();
|
||||
for el in self {
|
||||
el.clone_from(value)
|
||||
if let Some((last, elems)) = self.split_last_mut() {
|
||||
for el in elems {
|
||||
el.clone_from(&value);
|
||||
}
|
||||
|
||||
*last = value
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ authors = ["The Rust Project Developers"]
|
||||
name = "rustc_attr"
|
||||
version = "0.0.0"
|
||||
edition = "2018"
|
||||
build = "build.rs"
|
||||
|
||||
[lib]
|
||||
name = "rustc_attr"
|
||||
@ -19,3 +20,4 @@ rustc_feature = { path = "../librustc_feature" }
|
||||
rustc_macros = { path = "../librustc_macros" }
|
||||
rustc_session = { path = "../librustc_session" }
|
||||
rustc_ast = { path = "../librustc_ast" }
|
||||
version_check = "0.9"
|
||||
|
4
src/librustc_attr/build.rs
Normal file
4
src/librustc_attr/build.rs
Normal file
@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
println!("cargo:rerun-if-env-changed=CFG_VERSION");
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
|
||||
use super::{find_by_name, mark_used};
|
||||
|
||||
use rustc_ast::ast::{self, Attribute, MetaItem, MetaItemKind, NestedMetaItem};
|
||||
use rustc_ast::ast::{self, Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::{struct_span_err, Applicability, Handler};
|
||||
use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
|
||||
@ -11,6 +11,7 @@ use rustc_session::parse::{feature_err, ParseSess};
|
||||
use rustc_span::hygiene::Transparency;
|
||||
use rustc_span::{symbol::sym, symbol::Symbol, Span};
|
||||
use std::num::NonZeroU32;
|
||||
use version_check::Version;
|
||||
|
||||
pub fn is_builtin_attr(attr: &Attribute) -> bool {
|
||||
attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some()
|
||||
@ -568,11 +569,8 @@ pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
|
||||
|
||||
/// Tests if a cfg-pattern matches the cfg set
|
||||
pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) -> bool {
|
||||
eval_condition(cfg, sess, &mut |cfg| {
|
||||
let gate = find_gated_cfg(|sym| cfg.check_name(sym));
|
||||
if let (Some(feats), Some(gated_cfg)) = (features, gate) {
|
||||
gate_cfg(&gated_cfg, cfg.span, sess, feats);
|
||||
}
|
||||
eval_condition(cfg, sess, features, &mut |cfg| {
|
||||
try_gate_cfg(cfg, sess, features);
|
||||
let error = |span, msg| {
|
||||
sess.span_diagnostic.span_err(span, msg);
|
||||
true
|
||||
@ -603,6 +601,13 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat
|
||||
})
|
||||
}
|
||||
|
||||
fn try_gate_cfg(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) {
|
||||
let gate = find_gated_cfg(|sym| cfg.check_name(sym));
|
||||
if let (Some(feats), Some(gated_cfg)) = (features, gate) {
|
||||
gate_cfg(&gated_cfg, cfg.span, sess, feats);
|
||||
}
|
||||
}
|
||||
|
||||
fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &ParseSess, features: &Features) {
|
||||
let (cfg, feature, has_feature) = gated_cfg;
|
||||
if !has_feature(features) && !cfg_span.allows_unstable(*feature) {
|
||||
@ -616,9 +621,41 @@ fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &ParseSess, features: &F
|
||||
pub fn eval_condition(
|
||||
cfg: &ast::MetaItem,
|
||||
sess: &ParseSess,
|
||||
features: Option<&Features>,
|
||||
eval: &mut impl FnMut(&ast::MetaItem) -> bool,
|
||||
) -> bool {
|
||||
match cfg.kind {
|
||||
ast::MetaItemKind::List(ref mis) if cfg.name_or_empty() == sym::version => {
|
||||
try_gate_cfg(cfg, sess, features);
|
||||
let (min_version, span) = match &mis[..] {
|
||||
[NestedMetaItem::Literal(Lit { kind: LitKind::Str(sym, ..), span, .. })] => {
|
||||
(sym, span)
|
||||
}
|
||||
[NestedMetaItem::Literal(Lit { span, .. })
|
||||
| NestedMetaItem::MetaItem(MetaItem { span, .. })] => {
|
||||
sess.span_diagnostic
|
||||
.struct_span_err(*span, &*format!("expected a version literal"))
|
||||
.emit();
|
||||
return false;
|
||||
}
|
||||
[..] => {
|
||||
sess.span_diagnostic
|
||||
.struct_span_err(cfg.span, "expected single version literal")
|
||||
.emit();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
let min_version = match Version::parse(&min_version.as_str()) {
|
||||
Some(ver) => ver,
|
||||
None => {
|
||||
sess.span_diagnostic.struct_span_err(*span, "invalid version literal").emit();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
let version = Version::parse(env!("CFG_VERSION")).unwrap();
|
||||
|
||||
version >= min_version
|
||||
}
|
||||
ast::MetaItemKind::List(ref mis) => {
|
||||
for mi in mis.iter() {
|
||||
if !mi.is_meta_item() {
|
||||
@ -634,12 +671,12 @@ pub fn eval_condition(
|
||||
// The unwraps below may look dangerous, but we've already asserted
|
||||
// that they won't fail with the loop above.
|
||||
match cfg.name_or_empty() {
|
||||
sym::any => {
|
||||
mis.iter().any(|mi| eval_condition(mi.meta_item().unwrap(), sess, eval))
|
||||
}
|
||||
sym::all => {
|
||||
mis.iter().all(|mi| eval_condition(mi.meta_item().unwrap(), sess, eval))
|
||||
}
|
||||
sym::any => mis
|
||||
.iter()
|
||||
.any(|mi| eval_condition(mi.meta_item().unwrap(), sess, features, eval)),
|
||||
sym::all => mis
|
||||
.iter()
|
||||
.all(|mi| eval_condition(mi.meta_item().unwrap(), sess, features, eval)),
|
||||
sym::not => {
|
||||
if mis.len() != 1 {
|
||||
struct_span_err!(
|
||||
@ -652,7 +689,7 @@ pub fn eval_condition(
|
||||
return false;
|
||||
}
|
||||
|
||||
!eval_condition(mis[0].meta_item().unwrap(), sess, eval)
|
||||
!eval_condition(mis[0].meta_item().unwrap(), sess, features, eval)
|
||||
}
|
||||
_ => {
|
||||
struct_span_err!(
|
||||
|
@ -4,6 +4,8 @@
|
||||
//! The goal is to move the definition of `MetaItem` and things that don't need to be in `syntax`
|
||||
//! to this crate.
|
||||
|
||||
#![feature(or_patterns)]
|
||||
|
||||
mod builtin;
|
||||
|
||||
pub use builtin::*;
|
||||
|
@ -141,10 +141,10 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
|
||||
SingleQuote => op!('\''),
|
||||
|
||||
Ident(name, false) if name == kw::DollarCrate => tt!(Ident::dollar_crate()),
|
||||
Ident(name, is_raw) => tt!(Ident::new(name, is_raw)),
|
||||
Ident(name, is_raw) => tt!(Ident::new(sess, name, is_raw)),
|
||||
Lifetime(name) => {
|
||||
let ident = ast::Ident::new(name, span).without_first_quote();
|
||||
stack.push(tt!(Ident::new(ident.name, false)));
|
||||
stack.push(tt!(Ident::new(sess, ident.name, false)));
|
||||
tt!(Punct::new('\'', true))
|
||||
}
|
||||
Literal(lit) => tt!(Literal { lit }),
|
||||
@ -322,7 +322,7 @@ impl Ident {
|
||||
false
|
||||
}
|
||||
}
|
||||
fn new(sym: Symbol, is_raw: bool, span: Span) -> Ident {
|
||||
fn new(sess: &ParseSess, sym: Symbol, is_raw: bool, span: Span) -> Ident {
|
||||
let sym = nfc_normalize(&sym.as_str());
|
||||
let string = sym.as_str();
|
||||
if !Self::is_valid(&string) {
|
||||
@ -331,6 +331,7 @@ impl Ident {
|
||||
if is_raw && !sym.can_be_raw() {
|
||||
panic!("`{}` cannot be a raw identifier", string);
|
||||
}
|
||||
sess.symbol_gallery.insert(sym, span);
|
||||
Ident { sym, is_raw, span }
|
||||
}
|
||||
fn dollar_crate(span: Span) -> Ident {
|
||||
@ -495,7 +496,7 @@ impl server::Punct for Rustc<'_> {
|
||||
|
||||
impl server::Ident for Rustc<'_> {
|
||||
fn new(&mut self, string: &str, span: Self::Span, is_raw: bool) -> Self::Ident {
|
||||
Ident::new(Symbol::intern(string), is_raw, span)
|
||||
Ident::new(self.sess, Symbol::intern(string), is_raw, span)
|
||||
}
|
||||
fn span(&mut self, ident: Self::Ident) -> Self::Span {
|
||||
ident.span
|
||||
|
@ -562,6 +562,9 @@ declare_features! (
|
||||
/// Allows the use of `#[target_feature]` on safe functions.
|
||||
(active, target_feature_11, "1.45.0", Some(69098), None),
|
||||
|
||||
/// Allow conditional compilation depending on rust version
|
||||
(active, cfg_version, "1.45.0", Some(64796), None),
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// feature-group-end: actual feature gates
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -26,6 +26,7 @@ const GATED_CFGS: &[GatedCfg] = &[
|
||||
(sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
|
||||
(sym::target_has_atomic_load_store, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
|
||||
(sym::sanitize, sym::cfg_sanitize, cfg_fn!(cfg_sanitize)),
|
||||
(sym::version, sym::cfg_version, cfg_fn!(cfg_version)),
|
||||
];
|
||||
|
||||
/// Find a gated cfg determined by the `pred`icate which is given the cfg's name.
|
||||
|
@ -657,7 +657,7 @@ where
|
||||
// Reset the ambient variance to covariant. This is needed
|
||||
// to correctly handle cases like
|
||||
//
|
||||
// for<'a> fn(&'a u32, &'a u3) == for<'b, 'c> fn(&'b u32, &'c u32)
|
||||
// for<'a> fn(&'a u32, &'a u32) == for<'b, 'c> fn(&'b u32, &'c u32)
|
||||
//
|
||||
// Somewhat surprisingly, these two types are actually
|
||||
// **equal**, even though the one on the right looks more
|
||||
|
@ -10,7 +10,7 @@ path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
unicode-security = "0.0.2"
|
||||
unicode-security = "0.0.3"
|
||||
rustc_middle = { path = "../librustc_middle" }
|
||||
rustc_ast_pretty = { path = "../librustc_ast_pretty" }
|
||||
rustc_attr = { path = "../librustc_attr" }
|
||||
|
@ -388,6 +388,11 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||
self.cur = push.prev;
|
||||
}
|
||||
|
||||
/// Find the lint level for a lint.
|
||||
pub fn lint_level(&self, lint: &'static Lint) -> (Level, LintSource) {
|
||||
self.sets.get_lint_level(lint, self.cur, None, self.sess)
|
||||
}
|
||||
|
||||
/// Used to emit a lint-related diagnostic based on the current state of
|
||||
/// this lint context.
|
||||
pub fn struct_lint(
|
||||
@ -396,7 +401,7 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||
span: Option<MultiSpan>,
|
||||
decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>),
|
||||
) {
|
||||
let (level, src) = self.sets.get_lint_level(lint, self.cur, None, self.sess);
|
||||
let (level, src) = self.lint_level(lint);
|
||||
struct_lint_level(self.sess, lint, level, src, span, decorate)
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,9 @@
|
||||
use crate::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_ast::ast;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_span::symbol::SymbolStr;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::Deref;
|
||||
|
||||
declare_lint! {
|
||||
pub NON_ASCII_IDENTS,
|
||||
@ -13,9 +17,144 @@ declare_lint! {
|
||||
"detects uncommon Unicode codepoints in identifiers"
|
||||
}
|
||||
|
||||
declare_lint_pass!(NonAsciiIdents => [NON_ASCII_IDENTS, UNCOMMON_CODEPOINTS]);
|
||||
// FIXME: Change this to warn.
|
||||
declare_lint! {
|
||||
pub CONFUSABLE_IDENTS,
|
||||
Allow,
|
||||
"detects visually confusable pairs between identifiers"
|
||||
}
|
||||
|
||||
declare_lint_pass!(NonAsciiIdents => [NON_ASCII_IDENTS, UNCOMMON_CODEPOINTS, CONFUSABLE_IDENTS]);
|
||||
|
||||
enum CowBoxSymStr {
|
||||
Interned(SymbolStr),
|
||||
Owned(Box<str>),
|
||||
}
|
||||
|
||||
impl Deref for CowBoxSymStr {
|
||||
type Target = str;
|
||||
|
||||
fn deref(&self) -> &str {
|
||||
match self {
|
||||
CowBoxSymStr::Interned(interned) => interned,
|
||||
CowBoxSymStr::Owned(ref owned) => owned,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for CowBoxSymStr {
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
Hash::hash(&**self, state)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<CowBoxSymStr> for CowBoxSymStr {
|
||||
#[inline]
|
||||
fn eq(&self, other: &CowBoxSymStr) -> bool {
|
||||
PartialEq::eq(&**self, &**other)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for CowBoxSymStr {}
|
||||
|
||||
fn calc_skeleton(symbol_str: SymbolStr, buffer: &'_ mut String) -> CowBoxSymStr {
|
||||
use std::mem::swap;
|
||||
use unicode_security::confusable_detection::skeleton;
|
||||
buffer.clear();
|
||||
buffer.extend(skeleton(&symbol_str));
|
||||
if symbol_str == *buffer {
|
||||
CowBoxSymStr::Interned(symbol_str)
|
||||
} else {
|
||||
let mut owned = String::new();
|
||||
swap(buffer, &mut owned);
|
||||
CowBoxSymStr::Owned(owned.into_boxed_str())
|
||||
}
|
||||
}
|
||||
|
||||
fn is_in_ascii_confusable_closure(c: char) -> bool {
|
||||
// FIXME: move this table to `unicode_security` crate.
|
||||
// data here corresponds to Unicode 13.
|
||||
const ASCII_CONFUSABLE_CLOSURE: &[(u64, u64)] = &[(0x00, 0x7f), (0xba, 0xba), (0x2080, 0x2080)];
|
||||
let c = c as u64;
|
||||
for &(range_start, range_end) in ASCII_CONFUSABLE_CLOSURE {
|
||||
if c >= range_start && c <= range_end {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn is_in_ascii_confusable_closure_relevant_list(c: char) -> bool {
|
||||
// FIXME: move this table to `unicode_security` crate.
|
||||
// data here corresponds to Unicode 13.
|
||||
const ASCII_CONFUSABLE_CLOSURE_RELEVANT_LIST: &[u64] = &[
|
||||
0x22, 0x25, 0x27, 0x2f, 0x30, 0x31, 0x49, 0x4f, 0x60, 0x6c, 0x6d, 0x6e, 0x72, 0x7c, 0xba,
|
||||
0x2080,
|
||||
];
|
||||
let c = c as u64;
|
||||
for &item in ASCII_CONFUSABLE_CLOSURE_RELEVANT_LIST {
|
||||
if c == item {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
impl EarlyLintPass for NonAsciiIdents {
|
||||
fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
|
||||
use rustc_session::lint::Level;
|
||||
if cx.builder.lint_level(CONFUSABLE_IDENTS).0 == Level::Allow {
|
||||
return;
|
||||
}
|
||||
let symbols = cx.sess.parse_sess.symbol_gallery.symbols.lock();
|
||||
let mut symbol_strs_and_spans = Vec::with_capacity(symbols.len());
|
||||
let mut in_fast_path = true;
|
||||
for (symbol, sp) in symbols.iter() {
|
||||
// fast path
|
||||
let symbol_str = symbol.as_str();
|
||||
if !symbol_str.chars().all(is_in_ascii_confusable_closure) {
|
||||
// fallback to slow path.
|
||||
symbol_strs_and_spans.clear();
|
||||
in_fast_path = false;
|
||||
break;
|
||||
}
|
||||
if symbol_str.chars().any(is_in_ascii_confusable_closure_relevant_list) {
|
||||
symbol_strs_and_spans.push((symbol_str, *sp));
|
||||
}
|
||||
}
|
||||
if !in_fast_path {
|
||||
// slow path
|
||||
for (symbol, sp) in symbols.iter() {
|
||||
let symbol_str = symbol.as_str();
|
||||
symbol_strs_and_spans.push((symbol_str, *sp));
|
||||
}
|
||||
}
|
||||
drop(symbols);
|
||||
symbol_strs_and_spans.sort_by_key(|x| x.0.clone());
|
||||
let mut skeleton_map =
|
||||
FxHashMap::with_capacity_and_hasher(symbol_strs_and_spans.len(), Default::default());
|
||||
let mut str_buf = String::new();
|
||||
for (symbol_str, sp) in symbol_strs_and_spans {
|
||||
let skeleton = calc_skeleton(symbol_str.clone(), &mut str_buf);
|
||||
skeleton_map
|
||||
.entry(skeleton)
|
||||
.and_modify(|(existing_symbolstr, existing_span)| {
|
||||
cx.struct_span_lint(CONFUSABLE_IDENTS, sp, |lint| {
|
||||
lint.build(&format!(
|
||||
"identifier pair considered confusable between `{}` and `{}`",
|
||||
existing_symbolstr, symbol_str
|
||||
))
|
||||
.span_label(
|
||||
*existing_span,
|
||||
"this is where the previous identifier occurred",
|
||||
)
|
||||
.emit();
|
||||
});
|
||||
})
|
||||
.or_insert((symbol_str, sp));
|
||||
}
|
||||
}
|
||||
fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: ast::Ident) {
|
||||
use unicode_security::GeneralSecurityProfile;
|
||||
let name_str = ident.name.as_str();
|
||||
|
@ -1123,11 +1123,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||
match self.kind(id) {
|
||||
EntryKind::Const(qualif, _)
|
||||
| EntryKind::AssocConst(
|
||||
AssocContainer::ImplDefault | AssocContainer::ImplFinal,
|
||||
AssocContainer::ImplDefault
|
||||
| AssocContainer::ImplFinal
|
||||
| AssocContainer::TraitWithDefault,
|
||||
qualif,
|
||||
_,
|
||||
) => qualif,
|
||||
_ => bug!(),
|
||||
_ => bug!("mir_const_qualif: unexpected kind"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,8 +222,9 @@ impl<'a> StringReader<'a> {
|
||||
ident_start = ident_start + BytePos(2);
|
||||
}
|
||||
let sym = nfc_normalize(self.str_from(ident_start));
|
||||
let span = self.mk_sp(start, self.pos);
|
||||
self.sess.symbol_gallery.insert(sym, span);
|
||||
if is_raw_ident {
|
||||
let span = self.mk_sp(start, self.pos);
|
||||
if !sym.can_be_raw() {
|
||||
self.err_span(span, &format!("`{}` cannot be a raw identifier", sym));
|
||||
}
|
||||
|
@ -60,6 +60,20 @@ impl GatedSpans {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SymbolGallery {
|
||||
/// All symbols occurred and their first occurrance span.
|
||||
pub symbols: Lock<FxHashMap<Symbol, Span>>,
|
||||
}
|
||||
|
||||
impl SymbolGallery {
|
||||
/// Insert a symbol and its span into symbol gallery.
|
||||
/// If the symbol has occurred before, ignore the new occurance.
|
||||
pub fn insert(&self, symbol: Symbol, span: Span) {
|
||||
self.symbols.lock().entry(symbol).or_insert(span);
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a diagnostic for a language feature error due to the given `span`.
|
||||
/// The `feature`'s `Symbol` is the one you used in `active.rs` and `rustc_span::symbols`.
|
||||
pub fn feature_err<'a>(
|
||||
@ -118,6 +132,7 @@ pub struct ParseSess {
|
||||
pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
|
||||
pub injected_crate_name: Once<Symbol>,
|
||||
pub gated_spans: GatedSpans,
|
||||
pub symbol_gallery: SymbolGallery,
|
||||
/// The parser has reached `Eof` due to an unclosed brace. Used to silence unnecessary errors.
|
||||
pub reached_eof: Lock<bool>,
|
||||
}
|
||||
@ -143,6 +158,7 @@ impl ParseSess {
|
||||
ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
|
||||
injected_crate_name: Once::new(),
|
||||
gated_spans: GatedSpans::default(),
|
||||
symbol_gallery: SymbolGallery::default(),
|
||||
reached_eof: Lock::new(false),
|
||||
}
|
||||
}
|
||||
|
@ -192,6 +192,7 @@ symbols! {
|
||||
cfg_target_has_atomic,
|
||||
cfg_target_thread_local,
|
||||
cfg_target_vendor,
|
||||
cfg_version,
|
||||
char,
|
||||
clippy,
|
||||
clone,
|
||||
@ -805,6 +806,7 @@ symbols! {
|
||||
var,
|
||||
vec,
|
||||
Vec,
|
||||
version,
|
||||
vis,
|
||||
visible_private_types,
|
||||
volatile,
|
||||
|
@ -81,7 +81,7 @@ impl<'tcx> OnUnimplementedDirective {
|
||||
None,
|
||||
)
|
||||
})?;
|
||||
attr::eval_condition(cond, &tcx.sess.parse_sess, &mut |_| true);
|
||||
attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |_| true);
|
||||
Some(cond.clone())
|
||||
};
|
||||
|
||||
@ -208,11 +208,16 @@ impl<'tcx> OnUnimplementedDirective {
|
||||
|
||||
for command in self.subcommands.iter().chain(Some(self)).rev() {
|
||||
if let Some(ref condition) = command.condition {
|
||||
if !attr::eval_condition(condition, &tcx.sess.parse_sess, &mut |c| {
|
||||
c.ident().map_or(false, |ident| {
|
||||
options.contains(&(ident.name, c.value_str().map(|s| s.to_string())))
|
||||
})
|
||||
}) {
|
||||
if !attr::eval_condition(
|
||||
condition,
|
||||
&tcx.sess.parse_sess,
|
||||
Some(tcx.features()),
|
||||
&mut |c| {
|
||||
c.ident().map_or(false, |ident| {
|
||||
options.contains(&(ident.name, c.value_str().map(|s| s.to_string())))
|
||||
})
|
||||
},
|
||||
) {
|
||||
debug!("evaluate: skipping {:?} due to condition", command);
|
||||
continue;
|
||||
}
|
||||
|
@ -9,3 +9,8 @@ impl PartialEq for CustomEq {
|
||||
|
||||
pub const NONE: Option<CustomEq> = None;
|
||||
pub const SOME: Option<CustomEq> = Some(CustomEq);
|
||||
|
||||
pub trait AssocConst {
|
||||
const NONE: Option<CustomEq> = None;
|
||||
const SOME: Option<CustomEq> = Some(CustomEq);
|
||||
}
|
||||
|
@ -4,7 +4,11 @@
|
||||
|
||||
extern crate consts;
|
||||
|
||||
struct Defaulted;
|
||||
impl consts::AssocConst for Defaulted {}
|
||||
|
||||
fn main() {
|
||||
let _ = Defaulted;
|
||||
match None {
|
||||
consts::SOME => panic!(),
|
||||
//~^ must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
@ -12,4 +16,12 @@ fn main() {
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match None {
|
||||
<Defaulted as consts::AssocConst>::SOME => panic!(),
|
||||
//~^ must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
//~| must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,26 @@
|
||||
error: to use a constant of type `consts::CustomEq` in a pattern, `consts::CustomEq` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/cross-crate-fail.rs:9:9
|
||||
--> $DIR/cross-crate-fail.rs:13:9
|
||||
|
|
||||
LL | consts::SOME => panic!(),
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: to use a constant of type `consts::CustomEq` in a pattern, `consts::CustomEq` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/cross-crate-fail.rs:9:9
|
||||
--> $DIR/cross-crate-fail.rs:21:9
|
||||
|
|
||||
LL | <Defaulted as consts::AssocConst>::SOME => panic!(),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: to use a constant of type `consts::CustomEq` in a pattern, `consts::CustomEq` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/cross-crate-fail.rs:13:9
|
||||
|
|
||||
LL | consts::SOME => panic!(),
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: to use a constant of type `consts::CustomEq` in a pattern, `consts::CustomEq` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/cross-crate-fail.rs:21:9
|
||||
|
|
||||
LL | <Defaulted as consts::AssocConst>::SOME => panic!(),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -6,9 +6,18 @@
|
||||
extern crate consts;
|
||||
use consts::CustomEq;
|
||||
|
||||
struct Defaulted;
|
||||
impl consts::AssocConst for Defaulted {}
|
||||
|
||||
fn main() {
|
||||
let _ = Defaulted;
|
||||
match Some(CustomEq) {
|
||||
consts::NONE => panic!(),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match Some(CustomEq) {
|
||||
<Defaulted as consts::AssocConst>::NONE => panic!(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
41
src/test/ui/feature-gates/feature-gate-cfg-version.rs
Normal file
41
src/test/ui/feature-gates/feature-gate-cfg-version.rs
Normal file
@ -0,0 +1,41 @@
|
||||
#[cfg(version("1.44"))]
|
||||
//~^ ERROR `cfg(version)` is experimental and subject to change
|
||||
fn foo() -> bool { true }
|
||||
#[cfg(not(version("1.44")))]
|
||||
//~^ ERROR `cfg(version)` is experimental and subject to change
|
||||
fn foo() -> bool { false }
|
||||
|
||||
#[cfg(version("1.43", "1.44", "1.45"))] //~ ERROR: expected single version literal
|
||||
//~^ ERROR `cfg(version)` is experimental and subject to change
|
||||
fn bar() -> bool { false }
|
||||
#[cfg(version(false))] //~ ERROR: expected a version literal
|
||||
//~^ ERROR `cfg(version)` is experimental and subject to change
|
||||
fn bar() -> bool { false }
|
||||
#[cfg(version("foo"))] //~ ERROR: invalid version literal
|
||||
//~^ ERROR `cfg(version)` is experimental and subject to change
|
||||
fn bar() -> bool { false }
|
||||
#[cfg(version("999"))]
|
||||
//~^ ERROR `cfg(version)` is experimental and subject to change
|
||||
fn bar() -> bool { false }
|
||||
#[cfg(version("-1"))] //~ ERROR: invalid version literal
|
||||
//~^ ERROR `cfg(version)` is experimental and subject to change
|
||||
fn bar() -> bool { false }
|
||||
#[cfg(version("65536"))] //~ ERROR: invalid version literal
|
||||
//~^ ERROR `cfg(version)` is experimental and subject to change
|
||||
fn bar() -> bool { false }
|
||||
#[cfg(version("0"))]
|
||||
//~^ ERROR `cfg(version)` is experimental and subject to change
|
||||
fn bar() -> bool { true }
|
||||
|
||||
#[cfg(version("1.65536.2"))]
|
||||
//~^ ERROR `cfg(version)` is experimental and subject to change
|
||||
fn version_check_bug() {}
|
||||
|
||||
fn main() {
|
||||
// This should fail but due to a bug in version_check `1.65536.2` is interpreted as `1.2`.
|
||||
// See https://github.com/SergioBenitez/version_check/issues/11
|
||||
version_check_bug();
|
||||
assert!(foo());
|
||||
assert!(bar());
|
||||
assert!(cfg!(version("1.42"))); //~ ERROR `cfg(version)` is experimental and subject to change
|
||||
}
|
132
src/test/ui/feature-gates/feature-gate-cfg-version.stderr
Normal file
132
src/test/ui/feature-gates/feature-gate-cfg-version.stderr
Normal file
@ -0,0 +1,132 @@
|
||||
error[E0658]: `cfg(version)` is experimental and subject to change
|
||||
--> $DIR/feature-gate-cfg-version.rs:1:7
|
||||
|
|
||||
LL | #[cfg(version("1.44"))]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #64796 <https://github.com/rust-lang/rust/issues/64796> for more information
|
||||
= help: add `#![feature(cfg_version)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `cfg(version)` is experimental and subject to change
|
||||
--> $DIR/feature-gate-cfg-version.rs:4:11
|
||||
|
|
||||
LL | #[cfg(not(version("1.44")))]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #64796 <https://github.com/rust-lang/rust/issues/64796> for more information
|
||||
= help: add `#![feature(cfg_version)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `cfg(version)` is experimental and subject to change
|
||||
--> $DIR/feature-gate-cfg-version.rs:8:7
|
||||
|
|
||||
LL | #[cfg(version("1.43", "1.44", "1.45"))]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #64796 <https://github.com/rust-lang/rust/issues/64796> for more information
|
||||
= help: add `#![feature(cfg_version)]` to the crate attributes to enable
|
||||
|
||||
error: expected single version literal
|
||||
--> $DIR/feature-gate-cfg-version.rs:8:7
|
||||
|
|
||||
LL | #[cfg(version("1.43", "1.44", "1.45"))]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0658]: `cfg(version)` is experimental and subject to change
|
||||
--> $DIR/feature-gate-cfg-version.rs:11:7
|
||||
|
|
||||
LL | #[cfg(version(false))]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #64796 <https://github.com/rust-lang/rust/issues/64796> for more information
|
||||
= help: add `#![feature(cfg_version)]` to the crate attributes to enable
|
||||
|
||||
error: expected a version literal
|
||||
--> $DIR/feature-gate-cfg-version.rs:11:15
|
||||
|
|
||||
LL | #[cfg(version(false))]
|
||||
| ^^^^^
|
||||
|
||||
error[E0658]: `cfg(version)` is experimental and subject to change
|
||||
--> $DIR/feature-gate-cfg-version.rs:14:7
|
||||
|
|
||||
LL | #[cfg(version("foo"))]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #64796 <https://github.com/rust-lang/rust/issues/64796> for more information
|
||||
= help: add `#![feature(cfg_version)]` to the crate attributes to enable
|
||||
|
||||
error: invalid version literal
|
||||
--> $DIR/feature-gate-cfg-version.rs:14:15
|
||||
|
|
||||
LL | #[cfg(version("foo"))]
|
||||
| ^^^^^
|
||||
|
||||
error[E0658]: `cfg(version)` is experimental and subject to change
|
||||
--> $DIR/feature-gate-cfg-version.rs:17:7
|
||||
|
|
||||
LL | #[cfg(version("999"))]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #64796 <https://github.com/rust-lang/rust/issues/64796> for more information
|
||||
= help: add `#![feature(cfg_version)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `cfg(version)` is experimental and subject to change
|
||||
--> $DIR/feature-gate-cfg-version.rs:20:7
|
||||
|
|
||||
LL | #[cfg(version("-1"))]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #64796 <https://github.com/rust-lang/rust/issues/64796> for more information
|
||||
= help: add `#![feature(cfg_version)]` to the crate attributes to enable
|
||||
|
||||
error: invalid version literal
|
||||
--> $DIR/feature-gate-cfg-version.rs:20:15
|
||||
|
|
||||
LL | #[cfg(version("-1"))]
|
||||
| ^^^^
|
||||
|
||||
error[E0658]: `cfg(version)` is experimental and subject to change
|
||||
--> $DIR/feature-gate-cfg-version.rs:23:7
|
||||
|
|
||||
LL | #[cfg(version("65536"))]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #64796 <https://github.com/rust-lang/rust/issues/64796> for more information
|
||||
= help: add `#![feature(cfg_version)]` to the crate attributes to enable
|
||||
|
||||
error: invalid version literal
|
||||
--> $DIR/feature-gate-cfg-version.rs:23:15
|
||||
|
|
||||
LL | #[cfg(version("65536"))]
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0658]: `cfg(version)` is experimental and subject to change
|
||||
--> $DIR/feature-gate-cfg-version.rs:26:7
|
||||
|
|
||||
LL | #[cfg(version("0"))]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #64796 <https://github.com/rust-lang/rust/issues/64796> for more information
|
||||
= help: add `#![feature(cfg_version)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `cfg(version)` is experimental and subject to change
|
||||
--> $DIR/feature-gate-cfg-version.rs:30:7
|
||||
|
|
||||
LL | #[cfg(version("1.65536.2"))]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #64796 <https://github.com/rust-lang/rust/issues/64796> for more information
|
||||
= help: add `#![feature(cfg_version)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `cfg(version)` is experimental and subject to change
|
||||
--> $DIR/feature-gate-cfg-version.rs:40:18
|
||||
|
|
||||
LL | assert!(cfg!(version("1.42")));
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #64796 <https://github.com/rust-lang/rust/issues/64796> for more information
|
||||
= help: add `#![feature(cfg_version)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -0,0 +1,9 @@
|
||||
#![feature(non_ascii_idents)]
|
||||
#![deny(confusable_idents)]
|
||||
#![allow(uncommon_codepoints, non_upper_case_globals)]
|
||||
|
||||
const s: usize = 42; //~ ERROR identifier pair considered confusable
|
||||
|
||||
fn main() {
|
||||
let s = "rust";
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
error: identifier pair considered confusable between `s` and `s`
|
||||
--> $DIR/lint-confusable-idents.rs:5:7
|
||||
|
|
||||
LL | const s: usize = 42;
|
||||
| ^^
|
||||
...
|
||||
LL | let s = "rust";
|
||||
| - this is where the previous identifier occurred
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/lint-confusable-idents.rs:2:9
|
||||
|
|
||||
LL | #![deny(confusable_idents)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user