Rollup merge of #135501 - tgross35:stdlib-dependencies-private, r=bjorn3

Inject `compiler_builtins` during postprocessing and ensure it is made private

Follow up of https://github.com/rust-lang/rust/pull/135278

Do the following:

* Inject `compiler_builtins` during postprocessing, rather than injecting `extern crate compiler_builtins as _` into the AST
* Do not make dependencies of `std` private by default (this was added in #135278)
* Make sure sysroot crates correctly mark their dependencies private/public
* Ensure that marking a dependency private makes its dependents private by default as well, unless otherwise specified
* Do the `compiler_builtins` update that has been blocked on this

There is more detail in the commit messages. This includes the changes I was working on in https://github.com/rust-lang/rust/pull/136226.

try-job: test-various
try-job: x86_64-msvc-1
try-job: x86_64-msvc-2
try-job: i686-mingw-1
try-job: i686-mingw-2
This commit is contained in:
Matthias Krüger 2025-02-23 00:16:18 +01:00 committed by GitHub
commit 1610bfb6af
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 227 additions and 110 deletions

View file

@ -19,16 +19,12 @@ pub fn inject(
let edition = sess.psess.edition;
// the first name in this list is the crate name of the crate with the prelude
let names: &[Symbol] = if attr::contains_name(pre_configured_attrs, sym::no_core) {
let name: Symbol = if attr::contains_name(pre_configured_attrs, sym::no_core) {
return 0;
} else if attr::contains_name(pre_configured_attrs, sym::no_std) {
if attr::contains_name(pre_configured_attrs, sym::compiler_builtins) {
&[sym::core]
sym::core
} else {
&[sym::core, sym::compiler_builtins]
}
} else {
&[sym::std]
sym::std
};
let expn_id = resolver.expansion_for_ast_pass(
@ -43,36 +39,16 @@ pub fn inject(
let ecfg = ExpansionConfig::default("std_lib_injection".to_string(), features);
let cx = ExtCtxt::new(sess, ecfg, resolver, None);
// .rev() to preserve ordering above in combination with insert(0, ...)
for &name in names.iter().rev() {
let ident_span = if edition >= Edition2018 { span } else { call_site };
let item = if name == sym::compiler_builtins {
// compiler_builtins is a private implementation detail. We only
// need to insert it into the crate graph for linking and should not
// expose any of its public API.
//
// FIXME(#113634) We should inject this during post-processing like
// we do for the panic runtime, profiler runtime, etc.
cx.item(
span,
Ident::new(kw::Underscore, ident_span),
thin_vec![],
ast::ItemKind::ExternCrate(Some(name)),
)
} else {
cx.item(
let item = cx.item(
span,
Ident::new(name, ident_span),
thin_vec![cx.attr_word(sym::macro_use, span)],
ast::ItemKind::ExternCrate(None),
)
};
krate.items.insert(0, item);
}
);
// The crates have been injected, the assumption is that the first one is
// the one with the prelude.
let name = names[0];
krate.items.insert(0, item);
let root = (edition == Edition2015).then_some(kw::PathRoot);
@ -88,6 +64,7 @@ pub fn inject(
.map(|&symbol| Ident::new(symbol, span))
.collect();
// Inject the relevant crate's prelude.
let use_item = cx.item(
span,
Ident::empty(),

View file

@ -15,7 +15,7 @@ index 7165c3e48af..968552ad435 100644
edition = "2021"
[dependencies]
core = { path = "../core" }
core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.146", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "=0.1.146", features = ['rustc-dep-of-std', 'no-f16-f128'] }

View file

@ -47,6 +47,9 @@ metadata_crate_dep_rustc_driver =
metadata_crate_location_unknown_type =
extern location for {$crate_name} is of an unknown type: {$path}
metadata_crate_not_compiler_builtins =
the crate `{$crate_name}` resolved as `compiler_builtins` but is not `#![compiler_builtins]`
metadata_crate_not_panic_runtime =
the crate `{$crate_name}` is not a panic runtime

View file

@ -32,7 +32,7 @@ use rustc_session::lint::{self, BuiltinLintDiag};
use rustc_session::output::validate_crate_name;
use rustc_session::search_paths::PathKind;
use rustc_span::edition::Edition;
use rustc_span::{DUMMY_SP, Ident, STDLIB_STABLE_CRATES, Span, Symbol, sym};
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym};
use rustc_target::spec::{PanicStrategy, Target, TargetTuple};
use tracing::{debug, info, trace};
@ -147,6 +147,7 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
writeln!(fmt, " cnum: {cnum}")?;
writeln!(fmt, " hash: {}", data.hash())?;
writeln!(fmt, " reqd: {:?}", data.dep_kind())?;
writeln!(fmt, " priv: {:?}", data.is_private_dep())?;
let CrateSource { dylib, rlib, rmeta } = data.source();
if let Some(dylib) = dylib {
writeln!(fmt, " dylib: {}", dylib.0.display())?;
@ -162,6 +163,53 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
}
}
/// Reason that a crate is being sourced as a dependency.
#[derive(Clone, Copy)]
enum CrateOrigin<'a> {
/// This crate was a dependency of another crate.
IndirectDependency {
/// Where this dependency was included from.
dep_root: &'a CratePaths,
/// True if the parent is private, meaning the dependent should also be private.
parent_private: bool,
/// Dependency info about this crate.
dep: &'a CrateDep,
},
/// Injected by `rustc`.
Injected,
/// Provided by `extern crate foo` or as part of the extern prelude.
Extern,
}
impl<'a> CrateOrigin<'a> {
/// Return the dependency root, if any.
fn dep_root(&self) -> Option<&'a CratePaths> {
match self {
CrateOrigin::IndirectDependency { dep_root, .. } => Some(dep_root),
_ => None,
}
}
/// Return dependency information, if any.
fn dep(&self) -> Option<&'a CrateDep> {
match self {
CrateOrigin::IndirectDependency { dep, .. } => Some(dep),
_ => None,
}
}
/// `Some(true)` if the dependency is private or its parent is private, `Some(false)` if the
/// dependency is not private, `None` if it could not be determined.
fn private_dep(&self) -> Option<bool> {
match self {
CrateOrigin::IndirectDependency { parent_private, dep, .. } => {
Some(dep.is_private || *parent_private)
}
_ => None,
}
}
}
impl CStore {
pub fn from_tcx(tcx: TyCtxt<'_>) -> FreezeReadGuard<'_, CStore> {
FreezeReadGuard::map(tcx.untracked().cstore.read(), |cstore| {
@ -497,25 +545,13 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
&self,
name: Symbol,
private_dep: Option<bool>,
dep_root: Option<&CratePaths>,
origin: CrateOrigin<'_>,
) -> bool {
// Standard library crates are never private.
if STDLIB_STABLE_CRATES.contains(&name) {
tracing::info!("returning false for {name} is private");
return false;
}
let extern_private = self.sess.opts.externs.get(name.as_str()).map(|e| e.is_private_dep);
// Any descendants of `std` should be private. These crates are usually not marked
// private in metadata, so we ignore that field.
if extern_private.is_none()
&& let Some(dep) = dep_root
&& STDLIB_STABLE_CRATES.contains(&dep.name)
{
if matches!(origin, CrateOrigin::Injected) {
return true;
}
let extern_private = self.sess.opts.externs.get(name.as_str()).map(|e| e.is_private_dep);
match (extern_private, private_dep) {
// Explicit non-private via `--extern`, explicit non-private from metadata, or
// unspecified with default to public.
@ -528,7 +564,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
fn register_crate(
&mut self,
host_lib: Option<Library>,
dep_root: Option<&CratePaths>,
origin: CrateOrigin<'_>,
lib: Library,
dep_kind: CrateDepKind,
name: Symbol,
@ -540,7 +576,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
let Library { source, metadata } = lib;
let crate_root = metadata.get_root();
let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash());
let private_dep = self.is_private_dep(name, private_dep, dep_root);
let private_dep = self.is_private_dep(name, private_dep, origin);
// Claim this crate number and cache it
let feed = self.cstore.intern_stable_crate_id(&crate_root, self.tcx)?;
@ -556,14 +592,15 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
// Maintain a reference to the top most crate.
// Stash paths for top-most crate locally if necessary.
let crate_paths;
let dep_root = if let Some(dep_root) = dep_root {
let dep_root = if let Some(dep_root) = origin.dep_root() {
dep_root
} else {
crate_paths = CratePaths::new(crate_root.name(), source.clone());
&crate_paths
};
let cnum_map = self.resolve_crate_deps(dep_root, &crate_root, &metadata, cnum, dep_kind)?;
let cnum_map =
self.resolve_crate_deps(dep_root, &crate_root, &metadata, cnum, dep_kind, private_dep)?;
let raw_proc_macros = if crate_root.is_proc_macro_crate() {
let temp_root;
@ -664,17 +701,19 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
name: Symbol,
span: Span,
dep_kind: CrateDepKind,
origin: CrateOrigin<'_>,
) -> Option<CrateNum> {
self.used_extern_options.insert(name);
match self.maybe_resolve_crate(name, dep_kind, None) {
match self.maybe_resolve_crate(name, dep_kind, origin) {
Ok(cnum) => {
self.cstore.set_used_recursively(cnum);
Some(cnum)
}
Err(err) => {
debug!("failed to resolve crate {} {:?}", name, dep_kind);
let missing_core =
self.maybe_resolve_crate(sym::core, CrateDepKind::Explicit, None).is_err();
let missing_core = self
.maybe_resolve_crate(sym::core, CrateDepKind::Explicit, CrateOrigin::Extern)
.is_err();
err.report(self.sess, span, missing_core);
None
}
@ -685,20 +724,20 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
&'b mut self,
name: Symbol,
mut dep_kind: CrateDepKind,
dep_of: Option<(&'b CratePaths, &'b CrateDep)>,
origin: CrateOrigin<'b>,
) -> Result<CrateNum, CrateError> {
info!("resolving crate `{}`", name);
if !name.as_str().is_ascii() {
return Err(CrateError::NonAsciiName(name));
}
let dep_root = dep_of.map(|d| d.0);
let dep = dep_of.map(|d| d.1);
let dep_root = origin.dep_root();
let dep = origin.dep();
let hash = dep.map(|d| d.hash);
let host_hash = dep.map(|d| d.host_hash).flatten();
let extra_filename = dep.map(|d| &d.extra_filename[..]);
let path_kind = if dep.is_some() { PathKind::Dependency } else { PathKind::Crate };
let private_dep = dep.map(|d| d.is_private);
let private_dep = origin.private_dep();
let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) {
(LoadResult::Previous(cnum), None)
@ -731,12 +770,12 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
match result {
(LoadResult::Previous(cnum), None) => {
info!("library for `{}` was loaded previously", name);
info!("library for `{}` was loaded previously, cnum {cnum}", name);
// When `private_dep` is none, it indicates the directly dependent crate. If it is
// not specified by `--extern` on command line parameters, it may be
// `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
// `public-dependency` here.
let private_dep = self.is_private_dep(name, private_dep, dep_root);
let private_dep = self.is_private_dep(name, private_dep, origin);
let data = self.cstore.get_crate_data_mut(cnum);
if data.is_proc_macro_crate() {
dep_kind = CrateDepKind::MacrosOnly;
@ -747,7 +786,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
}
(LoadResult::Loaded(library), host_library) => {
info!("register newly loaded library for `{}`", name);
self.register_crate(host_library, dep_root, library, dep_kind, name, private_dep)
self.register_crate(host_library, origin, library, dep_kind, name, private_dep)
}
_ => panic!(),
}
@ -783,6 +822,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
metadata: &MetadataBlob,
krate: CrateNum,
dep_kind: CrateDepKind,
parent_is_private: bool,
) -> Result<CrateNumMap, CrateError> {
debug!(
"resolving deps of external crate `{}` with dep root `{}`",
@ -801,17 +841,26 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
crate_num_map.push(krate);
for dep in deps {
info!(
"resolving dep `{}`->`{}` hash: `{}` extra filename: `{}`",
"resolving dep `{}`->`{}` hash: `{}` extra filename: `{}` private {}",
crate_root.name(),
dep.name,
dep.hash,
dep.extra_filename
dep.extra_filename,
dep.is_private,
);
let dep_kind = match dep_kind {
CrateDepKind::MacrosOnly => CrateDepKind::MacrosOnly,
_ => dep.kind,
};
let cnum = self.maybe_resolve_crate(dep.name, dep_kind, Some((dep_root, &dep)))?;
let cnum = self.maybe_resolve_crate(
dep.name,
dep_kind,
CrateOrigin::IndirectDependency {
dep_root,
parent_private: parent_is_private,
dep: &dep,
},
)?;
crate_num_map.push(cnum);
}
@ -905,7 +954,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
};
info!("panic runtime not found -- loading {}", name);
let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else {
let Some(cnum) =
self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, CrateOrigin::Injected)
else {
return;
};
let data = self.cstore.get_crate_data(cnum);
@ -934,7 +985,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
info!("loading profiler");
let name = Symbol::intern(&self.sess.opts.unstable_opts.profiler_runtime);
let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else {
let Some(cnum) =
self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, CrateOrigin::Injected)
else {
return;
};
let data = self.cstore.get_crate_data(cnum);
@ -1047,12 +1100,54 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
if entry.force {
let name_interned = Symbol::intern(name);
if !self.used_extern_options.contains(&name_interned) {
self.resolve_crate(name_interned, DUMMY_SP, CrateDepKind::Explicit);
self.resolve_crate(
name_interned,
DUMMY_SP,
CrateDepKind::Explicit,
CrateOrigin::Extern,
);
}
}
}
}
/// Inject the `compiler_builtins` crate if it is not already in the graph.
fn inject_compiler_builtins(&mut self, krate: &ast::Crate) {
// `compiler_builtins` does not get extern builtins, nor do `#![no_core]` crates
if attr::contains_name(&krate.attrs, sym::compiler_builtins)
|| attr::contains_name(&krate.attrs, sym::no_core)
{
info!("`compiler_builtins` unneeded");
return;
}
// If a `#![compiler_builtins]` crate already exists, avoid injecting it twice. This is
// the common case since usually it appears as a dependency of `std` or `alloc`.
for (cnum, cmeta) in self.cstore.iter_crate_data() {
if cmeta.is_compiler_builtins() {
info!("`compiler_builtins` already exists (cnum = {cnum}); skipping injection");
return;
}
}
// `compiler_builtins` is not yet in the graph; inject it. Error on resolution failure.
let Some(cnum) = self.resolve_crate(
sym::compiler_builtins,
krate.spans.inner_span.shrink_to_lo(),
CrateDepKind::Explicit,
CrateOrigin::Injected,
) else {
info!("`compiler_builtins` not resolved");
return;
};
// Sanity check that the loaded crate is `#![compiler_builtins]`
let cmeta = self.cstore.get_crate_data(cnum);
if !cmeta.is_compiler_builtins() {
self.dcx().emit_err(errors::CrateNotCompilerBuiltins { crate_name: cmeta.name() });
}
}
fn inject_dependency_if(
&mut self,
krate: CrateNum,
@ -1162,6 +1257,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
}
pub fn postprocess(&mut self, krate: &ast::Crate) {
self.inject_compiler_builtins(krate);
self.inject_forced_externs();
self.inject_profiler_runtime();
self.inject_allocator_crate(krate);
@ -1173,6 +1269,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
info!("{:?}", CrateDump(self.cstore));
}
/// Process an `extern crate foo` AST node.
pub fn process_extern_crate(
&mut self,
item: &ast::Item,
@ -1198,7 +1295,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
CrateDepKind::Explicit
};
let cnum = self.resolve_crate(name, item.span, dep_kind)?;
let cnum = self.resolve_crate(name, item.span, dep_kind, CrateOrigin::Extern)?;
let path_len = definitions.def_path(def_id).data.len();
self.cstore.update_extern_crate(
@ -1217,7 +1314,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
}
pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> Option<CrateNum> {
let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit)?;
let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit, CrateOrigin::Extern)?;
self.cstore.update_extern_crate(
cnum,
@ -1234,7 +1331,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
}
pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> {
self.maybe_resolve_crate(name, CrateDepKind::Explicit, None).ok()
self.maybe_resolve_crate(name, CrateDepKind::Explicit, CrateOrigin::Extern).ok()
}
}

View file

@ -332,6 +332,12 @@ pub struct CrateNotPanicRuntime {
pub crate_name: Symbol,
}
#[derive(Diagnostic)]
#[diag(metadata_crate_not_compiler_builtins)]
pub struct CrateNotCompilerBuiltins {
pub crate_name: Symbol,
}
#[derive(Diagnostic)]
#[diag(metadata_no_panic_strategy)]
pub struct NoPanicStrategy {

View file

@ -260,7 +260,7 @@ pub(crate) struct CrateLocator<'a> {
crate_rejections: CrateRejections,
}
#[derive(Clone)]
#[derive(Clone, Debug)]
pub(crate) struct CratePaths {
pub(crate) name: Symbol,
source: CrateSource,
@ -272,7 +272,7 @@ impl CratePaths {
}
}
#[derive(Copy, Clone, PartialEq)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub(crate) enum CrateFlavor {
Rlib,
Rmeta,
@ -893,13 +893,13 @@ fn get_flavor_from_path(path: &Path) -> CrateFlavor {
// ------------------------------------------ Error reporting -------------------------------------
#[derive(Clone)]
#[derive(Clone, Debug)]
struct CrateMismatch {
path: PathBuf,
got: String,
}
#[derive(Clone, Default)]
#[derive(Clone, Debug, Default)]
struct CrateRejections {
via_hash: Vec<CrateMismatch>,
via_triple: Vec<CrateMismatch>,
@ -912,6 +912,7 @@ struct CrateRejections {
/// Candidate rejection reasons collected during crate search.
/// If no candidate is accepted, then these reasons are presented to the user,
/// otherwise they are ignored.
#[derive(Debug)]
pub(crate) struct CombinedLocatorError {
crate_name: Symbol,
dep_root: Option<CratePaths>,
@ -921,6 +922,7 @@ pub(crate) struct CombinedLocatorError {
crate_rejections: CrateRejections,
}
#[derive(Debug)]
pub(crate) enum CrateError {
NonAsciiName(Symbol),
ExternLocationNotExist(Symbol, PathBuf),

View file

@ -1936,6 +1936,10 @@ impl CrateMetadata {
self.root.needs_panic_runtime
}
pub(crate) fn is_private_dep(&self) -> bool {
self.private_dep
}
pub(crate) fn is_panic_runtime(&self) -> bool {
self.root.panic_runtime
}
@ -1944,6 +1948,10 @@ impl CrateMetadata {
self.root.profiler_runtime
}
pub(crate) fn is_compiler_builtins(&self) -> bool {
self.root.compiler_builtins
}
pub(crate) fn needs_allocator(&self) -> bool {
self.root.needs_allocator
}

View file

@ -1,3 +1,5 @@
cargo-features = ["public-dependency"]
[package]
name = "alloc"
version = "0.0.0"
@ -9,7 +11,7 @@ autobenches = false
edition = "2021"
[dependencies]
core = { path = "../core" }
core = { path = "../core", public = true }
compiler_builtins = { version = "=0.1.146", features = ['rustc-dep-of-std'] }
[dev-dependencies]

View file

@ -388,7 +388,7 @@ mod uefi_command_internal {
}
}
pub fn start_image(&mut self) -> io::Result<r_efi::efi::Status> {
pub(crate) fn start_image(&mut self) -> io::Result<r_efi::efi::Status> {
self.update_st_crc32()?;
// Use our system table instead of the default one

View file

@ -84,7 +84,7 @@ pub(crate) mod system_time_internal {
// This algorithm is based on the one described in the post
// https://blog.reverberate.org/2020/05/12/optimizing-date-algorithms.html
pub const fn uefi_time_to_duration(t: r_efi::system::Time) -> Duration {
pub(crate) const fn uefi_time_to_duration(t: r_efi::system::Time) -> Duration {
assert!(t.month <= 12);
assert!(t.month != 0);

View file

@ -1,3 +1,5 @@
cargo-features = ["public-dependency"]
[package]
name = "sysroot"
version = "0.0.0"
@ -5,10 +7,10 @@ edition = "2021"
# this is a dummy crate to ensure that all required crates appear in the sysroot
[dependencies]
proc_macro = { path = "../proc_macro" }
proc_macro = { path = "../proc_macro", public = true }
profiler_builtins = { path = "../profiler_builtins", optional = true }
std = { path = "../std" }
test = { path = "../test" }
std = { path = "../std", public = true }
test = { path = "../test", public = true }
# Forward features to the `std` crate as necessary
[features]

View file

@ -1,3 +1,5 @@
cargo-features = ["public-dependency"]
[package]
name = "test"
version = "0.0.0"
@ -5,8 +7,8 @@ edition = "2021"
[dependencies]
getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] }
std = { path = "../std" }
core = { path = "../core" }
std = { path = "../std", public = true }
core = { path = "../core", public = true }
[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
libc = { version = "0.2.150", default-features = false }

View file

@ -7,11 +7,5 @@ error: unwinding panics are not supported without std
= help: using nightly cargo, use -Zbuild-std with panic="abort" to avoid unwinding
= note: since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem
error: requires `sized` lang_item
--> $DIR/empty-extern-arg.rs:6:11
|
LL | fn main() {}
| ^^
error: aborting due to 4 previous errors
error: aborting due to 3 previous errors

View file

@ -1,6 +1,5 @@
//@ aux-crate:priv:reexport=reexport.rs
//@ compile-flags: -Zunstable-options
//@ check-pass
// Checks the behavior of a reexported item from a private dependency.
@ -9,7 +8,7 @@
extern crate reexport;
// FIXME: This should trigger.
pub fn leaks_priv() -> reexport::Shared {
//~^ ERROR type `Shared` from private dependency 'shared' in public interface
reexport::Shared
}

View file

@ -0,0 +1,14 @@
error: type `Shared` from private dependency 'shared' in public interface
--> $DIR/reexport_from_priv.rs:11:1
|
LL | pub fn leaks_priv() -> reexport::Shared {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/reexport_from_priv.rs:7:9
|
LL | #![deny(exported_private_dependencies)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View file

@ -1,7 +1,6 @@
//@ aux-crate:priv:shared=shared.rs
//@ aux-crate:priv:indirect1=indirect1.rs
//@ compile-flags: -Zunstable-options
//@ check-pass
// A shared dependency, where it is only indirectly public.
//
@ -23,7 +22,7 @@
extern crate shared;
extern crate indirect1;
// FIXME: This should trigger.
pub fn leaks_priv() -> shared::Shared {
//~^ ERROR type `Shared` from private dependency 'shared' in public interface
shared::Shared
}

View file

@ -0,0 +1,14 @@
error: type `Shared` from private dependency 'shared' in public interface
--> $DIR/shared_indirect.rs:25:1
|
LL | pub fn leaks_priv() -> shared::Shared {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/shared_indirect.rs:20:9
|
LL | #![deny(exported_private_dependencies)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View file

@ -3,7 +3,8 @@
//@ edition:2018
//@ proc-macro: issue-59191.rs
//@ error-pattern: requires `sized` lang_item
//@ needs-unwind (affects error output)
//@ error-pattern: error: `#[panic_handler]` function required
#![feature(custom_inner_attributes)]
#![issue_59191::no_main]

View file

@ -1,10 +1,9 @@
error: requires `sized` lang_item
--> $DIR/issue-59191-replace-root-with-fn.rs:9:1
|
LL | #![issue_59191::no_main]
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the attribute macro `issue_59191::no_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: `#[panic_handler]` function required, but not found
error: aborting due to 1 previous error
error: unwinding panics are not supported without std
|
= help: using nightly cargo, use -Zbuild-std with panic="abort" to avoid unwinding
= note: since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem
error: aborting due to 2 previous errors

View file

@ -20,7 +20,6 @@ Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro
use core /* 0#1 */::prelude /* 0#1 */::rust_2018 /* 0#1 */::*;
#[macro_use /* 0#1 */]
extern crate core /* 0#1 */;
extern crate compiler_builtins /* NNN */ as _ /* 0#1 */;
// Don't load unnecessary hygiene information from std
extern crate std /* 0#0 */;

View file

@ -39,7 +39,6 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
use ::core /* 0#1 */::prelude /* 0#1 */::rust_2015 /* 0#1 */::*;
#[macro_use /* 0#1 */]
extern crate core /* 0#2 */;
extern crate compiler_builtins /* NNN */ as _ /* 0#2 */;
// Don't load unnecessary hygiene information from std
extern crate std /* 0#0 */;