Unify defined_lib_features and lib_features queries

This commit is contained in:
Michael Goulet
2023-09-23 05:38:49 +00:00
parent 46ecc10c69
commit 86299a1247
9 changed files with 85 additions and 62 deletions

View File

@@ -8,18 +8,14 @@ use rustc_ast::Attribute;
use rustc_attr::VERSION_PLACEHOLDER;
use rustc_hir::intravisit::Visitor;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::lib_features::LibFeatures;
use rustc_middle::query::Providers;
use rustc_middle::middle::lib_features::{FeatureStability, LibFeatures};
use rustc_middle::query::{LocalCrate, Providers};
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::Symbol;
use rustc_span::{sym, Span};
use crate::errors::{FeaturePreviouslyDeclared, FeatureStableTwice};
fn new_lib_features() -> LibFeatures {
LibFeatures { stable: Default::default(), unstable: Default::default() }
}
pub struct LibFeatureCollector<'tcx> {
tcx: TyCtxt<'tcx>,
lib_features: LibFeatures,
@@ -27,10 +23,10 @@ pub struct LibFeatureCollector<'tcx> {
impl<'tcx> LibFeatureCollector<'tcx> {
fn new(tcx: TyCtxt<'tcx>) -> LibFeatureCollector<'tcx> {
LibFeatureCollector { tcx, lib_features: new_lib_features() }
LibFeatureCollector { tcx, lib_features: LibFeatures::default() }
}
fn extract(&self, attr: &Attribute) -> Option<(Symbol, Option<Symbol>, Span)> {
fn extract(&self, attr: &Attribute) -> Option<(Symbol, FeatureStability, Span)> {
let stab_attrs = [
sym::stable,
sym::unstable,
@@ -72,8 +68,11 @@ impl<'tcx> LibFeatureCollector<'tcx> {
| sym::rustc_const_unstable
| sym::rustc_default_body_unstable
);
if since.is_some() || is_unstable {
return Some((feature, since, attr.span));
if is_unstable {
return Some((feature, FeatureStability::Unstable, attr.span));
}
if let Some(since) = since {
return Some((feature, FeatureStability::AcceptedSince(since), attr.span));
}
}
// We need to iterate over the other attributes, because
@@ -86,37 +85,43 @@ impl<'tcx> LibFeatureCollector<'tcx> {
None
}
fn collect_feature(&mut self, feature: Symbol, since: Option<Symbol>, span: Span) {
fn collect_feature(&mut self, feature: Symbol, stability: FeatureStability, span: Span) {
let already_in_stable = self.lib_features.stable.contains_key(&feature);
let already_in_unstable = self.lib_features.unstable.contains_key(&feature);
match (since, already_in_stable, already_in_unstable) {
(Some(since), _, false) => {
if let Some((prev_since, _)) = self.lib_features.stable.get(&feature) {
if *prev_since != since {
self.tcx.sess.emit_err(FeatureStableTwice {
span,
feature,
since,
prev_since: *prev_since,
});
return;
}
match (stability, already_in_stable, already_in_unstable) {
(FeatureStability::AcceptedSince(since), _, false) => {
if let Some((prev_since, _)) = self.lib_features.stable.get(&feature)
&& *prev_since != since
{
self.tcx.sess.emit_err(FeatureStableTwice {
span,
feature,
since,
prev_since: *prev_since,
});
return;
}
self.lib_features.stable.insert(feature, (since, span));
}
(None, false, _) => {
self.lib_features.unstable.insert(feature, span);
}
(Some(_), _, true) | (None, true, _) => {
let declared = if since.is_some() { "stable" } else { "unstable" };
let prev_declared = if since.is_none() { "stable" } else { "unstable" };
(FeatureStability::AcceptedSince(_), _, true) => {
self.tcx.sess.emit_err(FeaturePreviouslyDeclared {
span,
feature,
declared,
prev_declared,
declared: "stable",
prev_declared: "unstable",
});
}
(FeatureStability::Unstable, false, _) => {
self.lib_features.unstable.insert(feature, span);
}
(FeatureStability::Unstable, true, _) => {
self.tcx.sess.emit_err(FeaturePreviouslyDeclared {
span,
feature,
declared: "unstable",
prev_declared: "stable",
});
}
}
@@ -137,11 +142,11 @@ impl<'tcx> Visitor<'tcx> for LibFeatureCollector<'tcx> {
}
}
fn lib_features(tcx: TyCtxt<'_>, (): ()) -> LibFeatures {
fn lib_features(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> LibFeatures {
// If `staged_api` is not enabled then we aren't allowed to define lib
// features; there is no point collecting them.
if !tcx.features().staged_api {
return new_lib_features();
return LibFeatures::default();
}
let mut collector = LibFeatureCollector::new(tcx);