Skip to content

Commit

Permalink
Suggestion to wrap inner types using allocator_api in tuple
Browse files Browse the repository at this point in the history
  • Loading branch information
ken-matsui committed Nov 23, 2021
1 parent e90c5fb commit 57494f7
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 8 deletions.
61 changes: 53 additions & 8 deletions compiler/rustc_middle/src/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

pub use self::StabilityLevel::*;

use crate::ty::{self, TyCtxt};
use crate::ty::{self, DefIdTree, TyCtxt};
use rustc_ast::NodeId;
use rustc_attr::{self as attr, ConstStability, Deprecation, Stability};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
Expand Down Expand Up @@ -90,6 +90,7 @@ pub fn report_unstable(
feature: Symbol,
reason: Option<Symbol>,
issue: Option<NonZeroU32>,
suggestion: Option<(Span, String, String, Applicability)>,
is_soft: bool,
span: Span,
soft_handler: impl FnOnce(&'static Lint, Span, &str),
Expand All @@ -116,8 +117,12 @@ pub fn report_unstable(
if is_soft {
soft_handler(SOFT_UNSTABLE, span, &msg)
} else {
feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), &msg)
.emit();
let mut err =
feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), &msg);
if let Some((inner_types, ref msg, sugg, applicability)) = suggestion {
err.span_suggestion(inner_types, msg, sugg, applicability);
}
err.emit();
}
}
}
Expand Down Expand Up @@ -271,7 +276,13 @@ pub enum EvalResult {
Allow,
/// We cannot use the item because it is unstable and we did not provide the
/// corresponding feature gate.
Deny { feature: Symbol, reason: Option<Symbol>, issue: Option<NonZeroU32>, is_soft: bool },
Deny {
feature: Symbol,
reason: Option<Symbol>,
issue: Option<NonZeroU32>,
suggestion: Option<(Span, String, String, Applicability)>,
is_soft: bool,
},
/// The item does not have the `#[stable]` or `#[unstable]` marker assigned.
Unmarked,
}
Expand All @@ -292,6 +303,32 @@ fn skip_stability_check_due_to_privacy(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
}
}

// See issue #83250.
fn suggestion_for_allocator_api(
tcx: TyCtxt<'_>,
def_id: DefId,
span: Span,
feature: Symbol,
) -> Option<(Span, String, String, Applicability)> {
if feature == sym::allocator_api {
if let Some(trait_) = tcx.parent(def_id) {
if tcx.is_diagnostic_item(sym::Vec, trait_) {
let sm = tcx.sess.parse_sess.source_map();
let inner_types = sm.span_extend_to_prev_char(span, '<', true);
if let Ok(snippet) = sm.span_to_snippet(inner_types) {
return Some((
inner_types,
"consider wrapping the inner types in tuple".to_string(),
format!("({})", snippet),
Applicability::MaybeIncorrect,
));
}
}
}
}
None
}

impl<'tcx> TyCtxt<'tcx> {
/// Evaluates the stability of an item.
///
Expand Down Expand Up @@ -406,7 +443,8 @@ impl<'tcx> TyCtxt<'tcx> {
}
}

EvalResult::Deny { feature, reason, issue, is_soft }
let suggestion = suggestion_for_allocator_api(self, def_id, span, feature);
EvalResult::Deny { feature, reason, issue, suggestion, is_soft }
}
Some(_) => {
// Stable APIs are always ok to call and deprecated APIs are
Expand Down Expand Up @@ -457,9 +495,16 @@ impl<'tcx> TyCtxt<'tcx> {
};
match self.eval_stability(def_id, id, span, method_span) {
EvalResult::Allow => {}
EvalResult::Deny { feature, reason, issue, is_soft } => {
report_unstable(self.sess, feature, reason, issue, is_soft, span, soft_handler)
}
EvalResult::Deny { feature, reason, issue, suggestion, is_soft } => report_unstable(
self.sess,
feature,
reason,
issue,
suggestion,
is_soft,
span,
soft_handler,
),
EvalResult::Unmarked => unmarked(span, def_id),
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_resolve/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,7 @@ impl<'a> Resolver<'a> {
feature,
reason,
issue,
None,
is_soft,
span,
soft_handler,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ symbols! {
alloc_layout,
alloc_zeroed,
allocator,
allocator_api,
allocator_internals,
allow,
allow_fail,
Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/stability-attribute/suggest-vec-allocator-api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
fn main() {
let _: Vec<u8, _> = vec![]; //~ ERROR use of unstable library feature 'allocator_api'
#[rustfmt::skip]
let _: Vec<
String,
_> = vec![]; //~ ERROR use of unstable library feature 'allocator_api'
let _ = Vec::<u16, _>::new(); //~ ERROR use of unstable library feature 'allocator_api'
let _boxed: Box<u32, _> = Box::new(10); //~ ERROR use of unstable library feature 'allocator_api'
}
49 changes: 49 additions & 0 deletions src/test/ui/stability-attribute/suggest-vec-allocator-api.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
error[E0658]: use of unstable library feature 'allocator_api'
--> $DIR/suggest-vec-allocator-api.rs:2:20
|
LL | let _: Vec<u8, _> = vec![];
| ----^
| |
| help: consider wrapping the inner types in tuple: `(u8, _)`
|
= note: see issue #32838 <https://github.com/rust-lang/rust/issues/32838> for more information
= help: add `#![feature(allocator_api)]` to the crate attributes to enable

error[E0658]: use of unstable library feature 'allocator_api'
--> $DIR/suggest-vec-allocator-api.rs:6:9
|
LL | _> = vec![];
| ^
|
= note: see issue #32838 <https://github.com/rust-lang/rust/issues/32838> for more information
= help: add `#![feature(allocator_api)]` to the crate attributes to enable
help: consider wrapping the inner types in tuple
|
LL ~ let _: Vec<(
LL + String,
LL ~ _)> = vec![];
|

error[E0658]: use of unstable library feature 'allocator_api'
--> $DIR/suggest-vec-allocator-api.rs:8:26
|
LL | let _boxed: Box<u32, _> = Box::new(10);
| ^
|
= note: see issue #32838 <https://github.com/rust-lang/rust/issues/32838> for more information
= help: add `#![feature(allocator_api)]` to the crate attributes to enable

error[E0658]: use of unstable library feature 'allocator_api'
--> $DIR/suggest-vec-allocator-api.rs:7:24
|
LL | let _ = Vec::<u16, _>::new();
| -----^
| |
| help: consider wrapping the inner types in tuple: `(u16, _)`
|
= note: see issue #32838 <https://github.com/rust-lang/rust/issues/32838> for more information
= help: add `#![feature(allocator_api)]` to the crate attributes to enable

error: aborting due to 4 previous errors

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

0 comments on commit 57494f7

Please sign in to comment.