privacy: port "in public interface" diag
Signed-off-by: David Wood <david.wood@huawei.com>
This commit is contained in:
parent
0557d02a9d
commit
74f3a965f4
3 changed files with 60 additions and 12 deletions
|
@ -6,3 +6,7 @@ privacy-item-is-private = {$kind} `{$descr}` is private
|
||||||
.label = private {$kind}
|
.label = private {$kind}
|
||||||
privacy-unnamed-item-is-private = {$kind} is private
|
privacy-unnamed-item-is-private = {$kind} is private
|
||||||
.label = private {$kind}
|
.label = private {$kind}
|
||||||
|
|
||||||
|
privacy-in-public-interface = {$vis_descr} {$kind} `{$descr}` in public interface
|
||||||
|
.label = can't leak {$vis_descr} {$kind}
|
||||||
|
.visibility-label = `{$descr}` declared as {$vis_descr}
|
||||||
|
|
|
@ -45,3 +45,31 @@ pub struct UnnamedItemIsPrivate {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub kind: &'static str,
|
pub kind: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Duplicate of `InPublicInterface` but with a different error code, shares the same slug.
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[error(privacy::in_public_interface, code = "E0445")]
|
||||||
|
pub struct InPublicInterfaceTraits<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
pub vis_descr: &'static str,
|
||||||
|
pub kind: &'a str,
|
||||||
|
pub descr: String,
|
||||||
|
#[label(privacy::visibility_label)]
|
||||||
|
pub vis_span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Duplicate of `InPublicInterfaceTraits` but with a different error code, shares the same slug.
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[error(privacy::in_public_interface, code = "E0446")]
|
||||||
|
pub struct InPublicInterface<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
pub vis_descr: &'static str,
|
||||||
|
pub kind: &'a str,
|
||||||
|
pub descr: String,
|
||||||
|
#[label(privacy::visibility_label)]
|
||||||
|
pub vis_span: Span,
|
||||||
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ use rustc_ast::MacroDef;
|
||||||
use rustc_attr as attr;
|
use rustc_attr as attr;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_data_structures::intern::Interned;
|
use rustc_data_structures::intern::Interned;
|
||||||
use rustc_errors::struct_span_err;
|
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID};
|
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID};
|
||||||
|
@ -36,7 +35,10 @@ use std::marker::PhantomData;
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
use std::{cmp, fmt, mem};
|
use std::{cmp, fmt, mem};
|
||||||
|
|
||||||
use errors::{FieldIsPrivate, FieldIsPrivateLabel, ItemIsPrivate, UnnamedItemIsPrivate};
|
use errors::{
|
||||||
|
FieldIsPrivate, FieldIsPrivateLabel, InPublicInterface, InPublicInterfaceTraits, ItemIsPrivate,
|
||||||
|
UnnamedItemIsPrivate,
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// Generic infrastructure used to implement specific visitors below.
|
/// Generic infrastructure used to implement specific visitors below.
|
||||||
|
@ -1748,22 +1750,31 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let make_msg = || format!("{} {} `{}` in public interface", vis_descr, kind, descr);
|
|
||||||
let span = self.tcx.def_span(self.item_def_id.to_def_id());
|
let span = self.tcx.def_span(self.item_def_id.to_def_id());
|
||||||
if self.has_old_errors
|
if self.has_old_errors
|
||||||
|| self.in_assoc_ty
|
|| self.in_assoc_ty
|
||||||
|| self.tcx.resolutions(()).has_pub_restricted
|
|| self.tcx.resolutions(()).has_pub_restricted
|
||||||
{
|
{
|
||||||
let mut err = if kind == "trait" {
|
let descr = descr.to_string();
|
||||||
struct_span_err!(self.tcx.sess, span, E0445, "{}", make_msg())
|
|
||||||
} else {
|
|
||||||
struct_span_err!(self.tcx.sess, span, E0446, "{}", make_msg())
|
|
||||||
};
|
|
||||||
let vis_span =
|
let vis_span =
|
||||||
self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id));
|
self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id));
|
||||||
err.span_label(span, format!("can't leak {} {}", vis_descr, kind));
|
if kind == "trait" {
|
||||||
err.span_label(vis_span, format!("`{}` declared as {}", descr, vis_descr));
|
self.tcx.sess.emit_err(InPublicInterfaceTraits {
|
||||||
err.emit();
|
span,
|
||||||
|
vis_descr,
|
||||||
|
kind,
|
||||||
|
descr,
|
||||||
|
vis_span,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
self.tcx.sess.emit_err(InPublicInterface {
|
||||||
|
span,
|
||||||
|
vis_descr,
|
||||||
|
kind,
|
||||||
|
descr,
|
||||||
|
vis_span,
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let err_code = if kind == "trait" { "E0445" } else { "E0446" };
|
let err_code = if kind == "trait" { "E0445" } else { "E0446" };
|
||||||
self.tcx.struct_span_lint_hir(
|
self.tcx.struct_span_lint_hir(
|
||||||
|
@ -1771,7 +1782,12 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
|
||||||
hir_id,
|
hir_id,
|
||||||
span,
|
span,
|
||||||
|lint| {
|
|lint| {
|
||||||
lint.build(&format!("{} (error {})", make_msg(), err_code)).emit();
|
lint.build(&format!(
|
||||||
|
"{} (error {})",
|
||||||
|
format!("{} {} `{}` in public interface", vis_descr, kind, descr),
|
||||||
|
err_code
|
||||||
|
))
|
||||||
|
.emit();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue