Support unstable moves via stable in unstable items

This commit is contained in:
Jane Lusby 2022-04-11 18:12:26 -07:00 committed by Jane Losare-Lusby
parent 052495d001
commit e7fe5456c5
20 changed files with 200 additions and 18 deletions

View file

@ -471,13 +471,15 @@ impl<'tcx> TyCtxt<'tcx> {
///
/// This function will also check if the item is deprecated.
/// If so, and `id` is not `None`, a deprecated lint attached to `id` will be emitted.
///
/// Returns `true` if item is allowed aka, stable or unstable under an enabled feature.
pub fn check_stability(
self,
def_id: DefId,
id: Option<HirId>,
span: Span,
method_span: Option<Span>,
) {
) -> bool {
self.check_stability_allow_unstable(def_id, id, span, method_span, AllowUnstable::No)
}
@ -497,7 +499,7 @@ impl<'tcx> TyCtxt<'tcx> {
span: Span,
method_span: Option<Span>,
allow_unstable: AllowUnstable,
) {
) -> bool {
self.check_optional_stability(
def_id,
id,
@ -516,6 +518,8 @@ impl<'tcx> TyCtxt<'tcx> {
/// missing stability attributes (not necessarily just emit a `bug!`). This is necessary
/// for default generic parameters, which only have stability attributes if they were
/// added after the type on which they're defined.
///
/// Returns `true` if item is allowed aka, stable or unstable under an enabled feature.
pub fn check_optional_stability(
self,
def_id: DefId,
@ -524,13 +528,16 @@ impl<'tcx> TyCtxt<'tcx> {
method_span: Option<Span>,
allow_unstable: AllowUnstable,
unmarked: impl FnOnce(Span, DefId),
) {
) -> bool {
let soft_handler = |lint, span, msg: &_| {
self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| {
lint.build(msg).emit();
})
};
match self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable) {
let eval_result =
self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable);
let is_allowed = matches!(eval_result, EvalResult::Allow);
match eval_result {
EvalResult::Allow => {}
EvalResult::Deny { feature, reason, issue, suggestion, is_soft } => report_unstable(
self.sess,
@ -544,6 +551,8 @@ impl<'tcx> TyCtxt<'tcx> {
),
EvalResult::Unmarked => unmarked(span, def_id),
}
is_allowed
}
pub fn lookup_deprecation(self, id: DefId) -> Option<Deprecation> {

View file

@ -807,7 +807,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, id: hir::HirId) {
if let Some(def_id) = path.res.opt_def_id() {
let method_span = path.segments.last().map(|s| s.ident.span);
self.tcx.check_stability_allow_unstable(
let item_is_allowed = self.tcx.check_stability_allow_unstable(
def_id,
Some(id),
path.span,
@ -817,8 +817,33 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
} else {
AllowUnstable::No
},
)
);
if item_is_allowed {
// Check parent modules stability as well
//
// We check here rather than in `visit_path_segment` to prevent visiting the last
// path segment twice
let parents = path.segments.iter().rev().skip(1);
for path_segment in parents {
if let Some(def_id) = path_segment.res.as_ref().and_then(Res::opt_def_id) {
// use `None` for id to prevent deprecation check
self.tcx.check_stability_allow_unstable(
def_id,
None,
path.span,
None,
if is_unstable_reexport(self.tcx, id) {
AllowUnstable::Yes
} else {
AllowUnstable::No
},
)
}
}
}
}
intravisit::walk_path(self, path)
}
}

View file

@ -439,7 +439,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// as the rest of the type. As such, we ignore missing
// stability attributes.
},
)
);
}
if let (hir::TyKind::Infer, false) = (&ty.kind, self.astconv.allow_ty_infer()) {
self.inferred_params.push(ty.span);