Structured suggestion for "missing feature
in unstable fn call"
When encountering a call corresponding to an item marked as unstable behind a feature flag, provide a structured suggestion pointing at where in the crate the `#![feature(..)]` needs to be written. ``` error: `foobar` is not yet stable as a const fn --> $DIR/const-stability-attribute-implies-no-feature.rs:12:5 | LL | foobar(); | ^^^^^^^^ | help: add `#![feature(const_foobar)]` to the crate attributes to enable | LL + #![feature(const_foobar)] | ``` Fix #81370.
This commit is contained in:
parent
bcd0683e5d
commit
a47fee50bd
3 changed files with 25 additions and 4 deletions
|
@ -911,16 +911,23 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
// regular stability.
|
// regular stability.
|
||||||
feature == sym::rustc_private
|
feature == sym::rustc_private
|
||||||
&& issue == NonZero::new(27812)
|
&& issue == NonZero::new(27812)
|
||||||
&& self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked
|
&& tcx.sess.opts.unstable_opts.force_unstable_if_unmarked
|
||||||
};
|
};
|
||||||
// Even if the feature is enabled, we still need check_op to double-check
|
// Even if the feature is enabled, we still need check_op to double-check
|
||||||
// this if the callee is not safe to expose on stable.
|
// this if the callee is not safe to expose on stable.
|
||||||
if !feature_enabled || !callee_safe_to_expose_on_stable {
|
if !feature_enabled || !callee_safe_to_expose_on_stable {
|
||||||
|
let suggestion_span =
|
||||||
|
tcx.hir_crate_items(()).definitions().next().and_then(|id| {
|
||||||
|
tcx.crate_level_attribute_injection_span(
|
||||||
|
tcx.local_def_id_to_hir_id(id),
|
||||||
|
)
|
||||||
|
});
|
||||||
self.check_op(ops::FnCallUnstable {
|
self.check_op(ops::FnCallUnstable {
|
||||||
def_id: callee,
|
def_id: callee,
|
||||||
feature,
|
feature,
|
||||||
feature_enabled,
|
feature_enabled,
|
||||||
safe_to_expose_on_stable: callee_safe_to_expose_on_stable,
|
safe_to_expose_on_stable: callee_safe_to_expose_on_stable,
|
||||||
|
suggestion_span,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
//! Concrete error types for all operations which may be invalid in a certain const context.
|
//! Concrete error types for all operations which may be invalid in a certain const context.
|
||||||
|
|
||||||
use hir::{ConstContext, LangItem};
|
use hir::{ConstContext, LangItem};
|
||||||
use rustc_errors::Diag;
|
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
|
use rustc_errors::{Applicability, Diag};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
|
@ -388,6 +388,7 @@ pub(crate) struct FnCallUnstable {
|
||||||
/// expose on stable.
|
/// expose on stable.
|
||||||
pub feature_enabled: bool,
|
pub feature_enabled: bool,
|
||||||
pub safe_to_expose_on_stable: bool,
|
pub safe_to_expose_on_stable: bool,
|
||||||
|
pub suggestion_span: Option<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
|
impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
|
||||||
|
@ -407,8 +408,18 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
|
||||||
def_path: ccx.tcx.def_path_str(self.def_id),
|
def_path: ccx.tcx.def_path_str(self.def_id),
|
||||||
});
|
});
|
||||||
// FIXME: make this translatable
|
// FIXME: make this translatable
|
||||||
|
let msg = format!("add `#![feature({})]` to the crate attributes to enable", self.feature);
|
||||||
#[allow(rustc::untranslatable_diagnostic)]
|
#[allow(rustc::untranslatable_diagnostic)]
|
||||||
err.help(format!("add `#![feature({})]` to the crate attributes to enable", self.feature));
|
if let Some(span) = self.suggestion_span {
|
||||||
|
err.span_suggestion_verbose(
|
||||||
|
span,
|
||||||
|
msg,
|
||||||
|
format!("#![feature({})]\n", self.feature),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
err.help(msg);
|
||||||
|
}
|
||||||
|
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,10 @@ error: `foobar` is not yet stable as a const fn
|
||||||
LL | foobar();
|
LL | foobar();
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: add `#![feature(const_foobar)]` to the crate attributes to enable
|
help: add `#![feature(const_foobar)]` to the crate attributes to enable
|
||||||
|
|
|
||||||
|
LL + #![feature(const_foobar)]
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue