From 2ddf1b30439f49638d4575cb3fcca024c6ffde6a Mon Sep 17 00:00:00 2001 From: Jane Losare-Lusby Date: Wed, 4 May 2022 04:23:56 +0000 Subject: [PATCH] Initial commit working on edition based method disambiguation --- compiler/rustc_attr/src/builtin.rs | 10 ++++++-- compiler/rustc_passes/src/stability.rs | 2 +- compiler/rustc_span/src/symbol.rs | 1 + src/librustdoc/html/render/mod.rs | 2 +- .../auxiliary/edition-field-std.rs | 13 ++++++++++ .../ui/stability-attribute/edition-field.rs | 24 +++++++++++++++++++ .../clippy_utils/src/qualify_min_const_fn.rs | 2 +- 7 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/stability-attribute/auxiliary/edition-field-std.rs create mode 100644 src/test/ui/stability-attribute/edition-field.rs diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 8e748aaa58b59..e44bbfad99246 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -117,7 +117,7 @@ pub struct ConstStability { pub enum StabilityLevel { // Reason for the current stability level and the relevant rust-lang issue Unstable { reason: Option, issue: Option, is_soft: bool }, - Stable { since: Symbol }, + Stable { since: Symbol, edition: Option }, } impl StabilityLevel { @@ -348,6 +348,7 @@ where let mut feature = None; let mut since = None; + let mut edition = None; for meta in metas { match meta { NestedMetaItem::MetaItem(mi) => match mi.name_or_empty() { @@ -361,6 +362,11 @@ where continue 'outer; } } + sym::edition => { + if !get(mi, &mut edition) { + continue 'outer; + } + } _ => { handle_errors( &sess.parse_sess, @@ -386,7 +392,7 @@ where match (feature, since) { (Some(feature), Some(since)) => { - let level = Stable { since }; + let level = Stable { since, edition }; if sym::stable == meta_name { stab = Some((Stability { level, feature }, attr.span)); } else { diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 10dc587be6e48..63efcfc34c61a 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -224,7 +224,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { // Check if deprecated_since < stable_since. If it is, // this is *almost surely* an accident. - if let (&Some(dep_since), &attr::Stable { since: stab_since }) = + if let (&Some(dep_since), &attr::Stable { since: stab_since, ..}) = (&depr.as_ref().and_then(|(d, _)| d.since), &stab.level) { // Explicit version of iter::order::lt to handle parse errors properly diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c1299c94c4bb3..b7ed03ee008e8 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -613,6 +613,7 @@ symbols! { dyn_metadata, dyn_trait, e, + edition, edition_macro_pats, edition_panic, eh_catch_typeinfo, diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index fedeb449b2e0e..22de0396e8f0a 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -845,7 +845,7 @@ fn render_stability_since_raw( } let const_title_and_stability = match const_stability { - Some(ConstStability { level: StabilityLevel::Stable { since }, .. }) + Some(ConstStability { level: StabilityLevel::Stable { since, .. }, .. }) if Some(since) != containing_const_ver => { Some((format!("const since {}", since), format!("const: {}", since))) diff --git a/src/test/ui/stability-attribute/auxiliary/edition-field-std.rs b/src/test/ui/stability-attribute/auxiliary/edition-field-std.rs new file mode 100644 index 0000000000000..6d52af90e0b91 --- /dev/null +++ b/src/test/ui/stability-attribute/auxiliary/edition-field-std.rs @@ -0,0 +1,13 @@ +#![feature(staged_api)] +#![stable(feature = "intersperse", since = "1.0.0", edition = "2021")] + +#[stable(feature = "intersperse", since = "1.0.0", edition = "2021")] +pub struct Intersperse; + +#[stable(feature = "intersperse", since = "1.0.0", edition = "2021")] +pub trait Iterator { + #[stable(feature = "intersperse", since = "1.0.0", edition = "2021")] + fn intersperse(&self, separator: ()) -> Intersperse { + unimplemented!() + } +} diff --git a/src/test/ui/stability-attribute/edition-field.rs b/src/test/ui/stability-attribute/edition-field.rs new file mode 100644 index 0000000000000..2965c437eae15 --- /dev/null +++ b/src/test/ui/stability-attribute/edition-field.rs @@ -0,0 +1,24 @@ +// aux-build:edition-field-std.rs + +extern crate edition_field_std; +use edition_field_std::Iterator; + +struct Intersperse; + +trait Itertools { + fn intersperse(&self, separator: ()) -> Intersperse { + unimplemented!() + } +} + +impl Itertools for T +where + T: Iterator {} + +struct MyIterator; +impl Iterator for MyIterator {} + +fn main() { + let it = MyIterator; + let _intersperse = it.intersperse(()); +} diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index fe41122048489..3c3f9e7d7a3e4 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -355,7 +355,7 @@ fn check_terminator<'a, 'tcx>( fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: Option<&RustcVersion>) -> bool { tcx.is_const_fn(def_id) && tcx.lookup_const_stability(def_id).map_or(true, |const_stab| { - if let rustc_attr::StabilityLevel::Stable { since } = const_stab.level { + if let rustc_attr::StabilityLevel::Stable { since, ..} = const_stab.level { // Checking MSRV is manually necessary because `rustc` has no such concept. This entire // function could be removed if `rustc` provided a MSRV-aware version of `is_const_fn`. // as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262.