Suggestion to wrap inner types using allocator_api in tuple

This commit is contained in:
Ken Matsui 2021-11-13 16:39:54 +09:00
parent e90c5fbbc5
commit 57494f7c75
No known key found for this signature in database
GPG Key ID: 103360B3298EE433
5 changed files with 113 additions and 8 deletions

View File

@ -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};
@ -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),
@ -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();
}
}
}
@ -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,
}
@ -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.
///
@ -406,7 +443,8 @@ pub fn eval_stability(
}
}
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
@ -457,9 +495,16 @@ pub fn check_optional_stability(
};
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),
}
}

View File

@ -1133,6 +1133,7 @@ fn check_stability_and_deprecation(
feature,
reason,
issue,
None,
is_soft,
span,
soft_handler,

View File

@ -308,6 +308,7 @@
alloc_layout,
alloc_zeroed,
allocator,
allocator_api,
allocator_internals,
allow,
allow_fail,

View File

@ -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'
}

View File

@ -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`.