From fc76015dcb77ce86aa2df98c33a8e9cf36c16352 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 22 May 2024 11:47:32 +0200 Subject: [PATCH 01/12] Migrate `run-make/rustdoc-scrape-examples-macros` to `rmake.rs` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../rustdoc-scrape-examples-macros/Makefile | 19 ------ .../rustdoc-scrape-examples-macros/rmake.rs | 64 +++++++++++++++++++ 3 files changed, 64 insertions(+), 20 deletions(-) delete mode 100644 tests/run-make/rustdoc-scrape-examples-macros/Makefile create mode 100644 tests/run-make/rustdoc-scrape-examples-macros/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 96fb8e27e6d21..54912cdd2548d 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -233,7 +233,6 @@ run-make/rlib-format-packed-bundled-libs/Makefile run-make/rmeta-preferred/Makefile run-make/rustc-macro-dep-files/Makefile run-make/rustdoc-io-error/Makefile -run-make/rustdoc-scrape-examples-macros/Makefile run-make/rustdoc-verify-output-files/Makefile run-make/rustdoc-with-output-option/Makefile run-make/rustdoc-with-short-out-dir-option/Makefile diff --git a/tests/run-make/rustdoc-scrape-examples-macros/Makefile b/tests/run-make/rustdoc-scrape-examples-macros/Makefile deleted file mode 100644 index edc19d8cb5de4..0000000000000 --- a/tests/run-make/rustdoc-scrape-examples-macros/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# ignore-cross-compile -include ../../run-make/tools.mk - -OUTPUT_DIR := "$(TMPDIR)/rustdoc" -DYLIB_NAME := $(shell echo | $(RUSTC) --crate-name foobar_macro --crate-type dylib --print file-names -) - -all: - $(RUSTC) src/proc.rs --crate-name foobar_macro --edition=2021 --crate-type proc-macro --emit=dep-info,link - - $(RUSTC) src/lib.rs --crate-name foobar --edition=2021 --crate-type lib --emit=dep-info,link - - $(RUSTDOC) examples/ex.rs --crate-name ex --crate-type bin --output $(OUTPUT_DIR) \ - --extern foobar=$(TMPDIR)/libfoobar.rlib --extern foobar_macro=$(TMPDIR)/$(DYLIB_NAME) \ - -Z unstable-options --scrape-examples-output-path $(TMPDIR)/ex.calls --scrape-examples-target-crate foobar - - $(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --output $(OUTPUT_DIR) \ - -Z unstable-options --with-examples $(TMPDIR)/ex.calls - - $(HTMLDOCCK) $(OUTPUT_DIR) src/lib.rs diff --git a/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs b/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs new file mode 100644 index 0000000000000..81b7defafc6c0 --- /dev/null +++ b/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs @@ -0,0 +1,64 @@ +//@ ignore-cross-compile + +use run_make_support::{htmldocck, rustc, rustdoc, tmp_dir}; + +fn main() { + let tmp_dir = tmp_dir(); + let out_dir = tmp_dir.join("rustdoc"); + let ex_dir = tmp_dir.join("ex.calls"); + let proc_crate_name = "foobar_macro"; + let crate_name = "foobar"; + + let dylib_name = String::from_utf8( + rustc() + .crate_name(proc_crate_name) + .crate_type("dylib") + .arg("--print") + .arg("file-names") + .arg("-") + .command_output() + .stdout, + ) + .unwrap(); + + rustc() + .input("src/proc.rs") + .crate_name(proc_crate_name) + .edition("2021") + .crate_type("proc-macro") + .emit("dep-info,link") + .run(); + rustc() + .input("src/lib.rs") + .crate_name(crate_name) + .edition("2021") + .crate_type("lib") + .emit("dep-info,link") + .run(); + + rustdoc() + .input("examples/ex.rs") + .crate_name("ex") + .crate_type("bin") + .output(&out_dir) + .extern_(crate_name, tmp_dir.join(format!("lib{crate_name}.rlib"))) + .extern_(proc_crate_name, tmp_dir.join(dylib_name.trim())) + .arg("-Zunstable-options") + .arg("--scrape-examples-output-path") + .arg(&ex_dir) + .arg("--scrape-examples-target-crate") + .arg(crate_name) + .run(); + + rustdoc() + .input("src/lib.rs") + .crate_name(crate_name) + .crate_type("lib") + .output(&out_dir) + .arg("-Zunstable-options") + .arg("--with-examples") + .arg(&ex_dir) + .run(); + + assert!(htmldocck().arg(out_dir).arg("src/lib.rs").status().unwrap().success()); +} From 87b77a2a2c32e293d673a682bab6d53ac528c207 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Wed, 22 May 2024 15:18:29 +0200 Subject: [PATCH 02/12] Directly add extension instead of using `Path::with_extension` `Path::with_extension` has a nice footgun when the original path doesn't contain an extension: Anything after the last dot gets removed. --- compiler/rustc_codegen_llvm/src/back/archive.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index c304c0cbd3bd5..2cc44357eba47 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -127,11 +127,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { is_direct_dependency: bool, ) -> PathBuf { let name_suffix = if is_direct_dependency { "_imports" } else { "_imports_indirect" }; - let output_path = { - let mut output_path: PathBuf = tmpdir.to_path_buf(); - output_path.push(format!("{lib_name}{name_suffix}")); - output_path.with_extension("lib") - }; + let output_path = tmpdir.join(format!("{lib_name}{name_suffix}.lib")); let target = &sess.target; let mingw_gnu_toolchain = common::is_mingw_gnu_toolchain(target); @@ -157,7 +153,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { // functions. Therefore, use binutils to create the import library instead, // by writing a .DEF file to the temp dir and calling binutils's dlltool. let def_file_path = - tmpdir.join(format!("{lib_name}{name_suffix}")).with_extension("def"); + tmpdir.join(format!("{lib_name}{name_suffix}.def")); let def_file_content = format!( "EXPORTS\n{}", From 72968e519834213d69989271fd6dfb2cdc64493c Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Wed, 22 May 2024 15:54:02 +0200 Subject: [PATCH 03/12] Rename `FrameworkOnlyWindows` to `RawDylibOnlyWindows` Frameworks are Apple-specific, no idea why it had "framework" in the name before. --- compiler/rustc_metadata/messages.ftl | 6 +++--- compiler/rustc_metadata/src/errors.rs | 4 ++-- compiler/rustc_metadata/src/native_libs.rs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl index 2f5dfad265c80..932603cd6b267 100644 --- a/compiler/rustc_metadata/messages.ftl +++ b/compiler/rustc_metadata/messages.ftl @@ -91,9 +91,6 @@ metadata_found_staticlib = found staticlib `{$crate_name}` instead of rlib or dylib{$add_info} .help = please recompile that crate using --crate-type lib -metadata_framework_only_windows = - link kind `raw-dylib` is only supported on Windows targets - metadata_global_alloc_required = no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait @@ -233,6 +230,9 @@ metadata_profiler_builtins_needs_core = metadata_raw_dylib_no_nul = link name must not contain NUL characters if link kind is `raw-dylib` +metadata_raw_dylib_only_windows = + link kind `raw-dylib` is only supported on Windows targets + metadata_renaming_no_link = renaming of the library `{$lib_name}` was specified, however this crate contains no `#[link(...)]` attributes referencing this library diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index fb0010f2c5d2e..47d183a044040 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -142,8 +142,8 @@ pub struct LinkFrameworkApple { } #[derive(Diagnostic)] -#[diag(metadata_framework_only_windows, code = E0455)] -pub struct FrameworkOnlyWindows { +#[diag(metadata_raw_dylib_only_windows, code = E0455)] +pub struct RawDylibOnlyWindows { #[primary_span] pub span: Span, } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 58760be921a61..1254ebead0727 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -151,7 +151,7 @@ impl<'tcx> Collector<'tcx> { } "raw-dylib" => { if !sess.target.is_like_windows { - sess.dcx().emit_err(errors::FrameworkOnlyWindows { span }); + sess.dcx().emit_err(errors::RawDylibOnlyWindows { span }); } NativeLibKind::RawDylib } From 8369dbba4360f783b84cfb13304329ae1cbd092f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 22 May 2024 12:46:08 -0400 Subject: [PATCH 04/12] Use correct param-env in MissingCopyImplementations --- compiler/rustc_lint/src/builtin.rs | 9 ++++---- .../lint/missing_copy_impl_trivial_bounds.rs | 21 +++++++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 tests/ui/lint/missing_copy_impl_trivial_bounds.rs diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 0f059bceae7cb..a3a8e5199ff73 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -674,11 +674,10 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { return; } } - let param_env = ty::ParamEnv::empty(); - if ty.is_copy_modulo_regions(cx.tcx, param_env) { + if ty.is_copy_modulo_regions(cx.tcx, cx.param_env) { return; } - if type_implements_negative_copy_modulo_regions(cx.tcx, ty, param_env) { + if type_implements_negative_copy_modulo_regions(cx.tcx, ty, cx.param_env) { return; } if def.is_variant_list_non_exhaustive() @@ -694,7 +693,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { .tcx .infer_ctxt() .build() - .type_implements_trait(iter_trait, [ty], param_env) + .type_implements_trait(iter_trait, [ty], cx.param_env) .must_apply_modulo_regions() { return; @@ -711,7 +710,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { if type_allowed_to_implement_copy( cx.tcx, - param_env, + cx.param_env, ty, traits::ObligationCause::misc(item.span, item.owner_id.def_id), ) diff --git a/tests/ui/lint/missing_copy_impl_trivial_bounds.rs b/tests/ui/lint/missing_copy_impl_trivial_bounds.rs new file mode 100644 index 0000000000000..9b743417bd52b --- /dev/null +++ b/tests/ui/lint/missing_copy_impl_trivial_bounds.rs @@ -0,0 +1,21 @@ +//@ check-pass + +#![feature(trivial_bounds)] +#![allow(trivial_bounds)] + +// Make sure that we still use the where-clauses from the struct when checking +// if it may implement `Copy` unconditionally. +// Fix for . + +pub trait Foo { + type Assoc; +} + +pub struct Bar; + +// This needs to be public +pub struct Baz2(::Assoc) +where + Bar: Foo; + +fn main() {} From c8844dfdc00fbfe4b5e7839635214b744410312f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 20 May 2024 08:45:54 +1000 Subject: [PATCH 05/12] Clarify the meaning of the span within `mbe::TokenTree::MetaVar`. --- compiler/rustc_expand/src/mbe.rs | 3 ++- compiler/rustc_expand/src/mbe/quoted.rs | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_expand/src/mbe.rs b/compiler/rustc_expand/src/mbe.rs index a805c4fcf7b97..32d12c4fd0cc9 100644 --- a/compiler/rustc_expand/src/mbe.rs +++ b/compiler/rustc_expand/src/mbe.rs @@ -73,7 +73,8 @@ enum TokenTree { Delimited(DelimSpan, DelimSpacing, Delimited), /// A kleene-style repetition sequence, e.g. `$($e:expr)*` (RHS) or `$($e),*` (LHS). Sequence(DelimSpan, SequenceRepetition), - /// e.g., `$var`. + /// e.g., `$var`. The span covers the leading dollar and the ident. (The span within the ident + /// only covers the ident, e.g. `var`.) MetaVar(Span, Ident), /// e.g., `$var:expr`. Only appears on the LHS. MetaVarDecl(Span, Ident /* name to bind */, Option), diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index d3ea48e2e2a8e..2e37fd70df9a7 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -176,7 +176,7 @@ fn parse_tree<'a>( // Depending on what `tree` is, we could be parsing different parts of a macro match tree { // `tree` is a `$` token. Look at the next token in `trees` - &tokenstream::TokenTree::Token(Token { kind: token::Dollar, span }, _) => { + &tokenstream::TokenTree::Token(Token { kind: token::Dollar, span: dollar_span }, _) => { // FIXME: Handle `Invisible`-delimited groups in a more systematic way // during parsing. let mut next = outer_trees.next(); @@ -209,7 +209,7 @@ fn parse_tree<'a>( err.emit(); // Returns early the same read `$` to avoid spanning // unrelated diagnostics that could be performed afterwards - return TokenTree::token(token::Dollar, span); + return TokenTree::token(token::Dollar, dollar_span); } Ok(elem) => { maybe_emit_macro_metavar_expr_feature( @@ -251,7 +251,7 @@ fn parse_tree<'a>( // special metavariable that names the crate of the invocation. Some(tokenstream::TokenTree::Token(token, _)) if token.is_ident() => { let (ident, is_raw) = token.ident().unwrap(); - let span = ident.span.with_lo(span.lo()); + let span = ident.span.with_lo(dollar_span.lo()); if ident.name == kw::Crate && matches!(is_raw, IdentIsRaw::No) { TokenTree::token(token::Ident(kw::DollarCrate, is_raw), span) } else { @@ -260,16 +260,19 @@ fn parse_tree<'a>( } // `tree` is followed by another `$`. This is an escaped `$`. - Some(&tokenstream::TokenTree::Token(Token { kind: token::Dollar, span }, _)) => { + Some(&tokenstream::TokenTree::Token( + Token { kind: token::Dollar, span: dollar_span2 }, + _, + )) => { if parsing_patterns { span_dollar_dollar_or_metavar_in_the_lhs_err( sess, - &Token { kind: token::Dollar, span }, + &Token { kind: token::Dollar, span: dollar_span2 }, ); } else { - maybe_emit_macro_metavar_expr_feature(features, sess, span); + maybe_emit_macro_metavar_expr_feature(features, sess, dollar_span2); } - TokenTree::token(token::Dollar, span) + TokenTree::token(token::Dollar, dollar_span2) } // `tree` is followed by some other token. This is an error. @@ -281,7 +284,7 @@ fn parse_tree<'a>( } // There are no more tokens. Just return the `$` we already have. - None => TokenTree::token(token::Dollar, span), + None => TokenTree::token(token::Dollar, dollar_span), } } From 3fc8f8998c45fbc211b98b5bae04cc87f8eb1619 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 20 May 2024 09:20:49 +1000 Subject: [PATCH 06/12] Clarify `parse` a little. - Name the colon span as `colon_span` to distinguish it from the other `span` local variable. - Just use basic pattern matching, which is easier to read than `map_or`. --- compiler/rustc_expand/src/mbe/quoted.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index 2e37fd70df9a7..8ad7cb15c92a9 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -62,7 +62,10 @@ pub(super) fn parse( match tree { TokenTree::MetaVar(start_sp, ident) if parsing_patterns => { let span = match trees.next() { - Some(&tokenstream::TokenTree::Token(Token { kind: token::Colon, span }, _)) => { + Some(&tokenstream::TokenTree::Token( + Token { kind: token::Colon, span: colon_span }, + _, + )) => { match trees.next() { Some(tokenstream::TokenTree::Token(token, _)) => match token.ident() { Some((fragment, _)) => { @@ -126,10 +129,12 @@ pub(super) fn parse( } _ => token.span, }, - tree => tree.map_or(span, tokenstream::TokenTree::span), + Some(tree) => tree.span(), + None => colon_span, } } - tree => tree.map_or(start_sp, tokenstream::TokenTree::span), + Some(tree) => tree.span(), + None => start_sp, }; result.push(TokenTree::MetaVarDecl(span, ident, None)); From b6de7821982caf99f58e2925ae3cb78673b31e24 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 17 May 2024 09:54:53 +1000 Subject: [PATCH 07/12] Clarify a comment. --- compiler/rustc_expand/src/proc_macro_server.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 1f3547c841a90..ec7e4416b9130 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -309,10 +309,10 @@ impl ToInternal> use rustc_ast::token::*; // The code below is conservative, using `token_alone`/`Spacing::Alone` - // in most places. When the resulting code is pretty-printed by - // `print_tts` it ends up with spaces between most tokens, which is - // safe but ugly. It's hard in general to do better when working at the - // token level. + // in most places. It's hard in general to do better when working at + // the token level. When the resulting code is pretty-printed by + // `print_tts` the `space_between` function helps avoid a lot of + // unnecessary whitespace, so the results aren't too bad. let (tree, rustc) = self; match tree { TokenTree::Punct(Punct { ch, joint, span }) => { From c679a5510222cb861a2a23088d1365707d1e0d6f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 17 May 2024 09:49:09 +1000 Subject: [PATCH 08/12] Convert some `token_joint_hidden` calls to `token_joint`. This has no noticeable effect, but it makes these cases follow the guidelines in the comments on `Spacing`, which say that `Joint` should be used "for each token that (a) should be pretty-printed without a space after it, and (b) is followed by a punctuation token". These two tokens are both followed by a comma, which is a punctuation token. --- compiler/rustc_builtin_macros/src/assert/context.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index 085ea3458bbfa..7814422611439 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -153,7 +153,7 @@ impl<'cx, 'a> Context<'cx, 'a> { fn build_panic(&self, expr_str: &str, panic_path: Path) -> P { let escaped_expr_str = escape_to_fmt(expr_str); let initial = [ - TokenTree::token_joint_hidden( + TokenTree::token_joint( token::Literal(token::Lit { kind: token::LitKind::Str, symbol: Symbol::intern(&if self.fmt_string.is_empty() { @@ -172,7 +172,7 @@ impl<'cx, 'a> Context<'cx, 'a> { ]; let captures = self.capture_decls.iter().flat_map(|cap| { [ - TokenTree::token_joint_hidden( + TokenTree::token_joint( token::Ident(cap.ident.name, IdentIsRaw::No), cap.ident.span, ), From a1b6d46e040176e63954ba3ba5bb18cd4ed3691a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 17 May 2024 08:23:24 +1000 Subject: [PATCH 09/12] Use `JointHidden` in a couple of suitable places. This has no notable effect, but it's appropriate because the relevant tokens are followed by delimiters. --- compiler/rustc_ast/src/tokenstream.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index fb666550e9302..3d46415507def 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -661,11 +661,11 @@ impl TokenStream { if attr_style == AttrStyle::Inner { vec![ TokenTree::token_joint(token::Pound, span), - TokenTree::token_alone(token::Not, span), + TokenTree::token_joint_hidden(token::Not, span), body, ] } else { - vec![TokenTree::token_alone(token::Pound, span), body] + vec![TokenTree::token_joint_hidden(token::Pound, span), body] } } } From 4d513cb4bf7d8c3151594096e97cd848f5fcab77 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 20 May 2024 12:54:38 +1000 Subject: [PATCH 10/12] Add some comments. --- compiler/rustc_ast_pretty/src/pprust/state.rs | 40 ++++++++++++++----- compiler/rustc_expand/src/mbe.rs | 2 + compiler/rustc_expand/src/mbe/transcribe.rs | 15 +++++++ 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 545b98a9135af..f02fe4cf0a728 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -681,22 +681,40 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere } } + // The easiest way to implement token stream pretty printing would be to + // print each token followed by a single space. But that would produce ugly + // output, so we go to some effort to do better. + // + // First, we track whether each token that appears in source code is + // followed by a space, with `Spacing`, and reproduce that in the output. + // This works well in a lot of cases. E.g. `stringify!(x + y)` produces + // "x + y" and `stringify!(x+y)` produces "x+y". + // + // But this doesn't work for code produced by proc macros (which have no + // original source text representation) nor for code produced by decl + // macros (which are tricky because the whitespace after tokens appearing + // in macro rules isn't always what you want in the produced output). For + // these we mostly use `Spacing::Alone`, which is the conservative choice. + // + // So we have a backup mechanism for when `Spacing::Alone` occurs between a + // pair of tokens: we check if that pair of tokens can obviously go + // together without a space between them. E.g. token `x` followed by token + // `,` is better printed as `x,` than `x ,`. (Even if the original source + // code was `x ,`.) + // + // Finally, we must be careful about changing the output. Token pretty + // printing is used by `stringify!` and `impl Display for + // proc_macro::TokenStream`, and some programs rely on the output having a + // particular form, even though they shouldn't. In particular, some proc + // macros do `format!({stream})` on a token stream and then "parse" the + // output with simple string matching that can't handle whitespace changes. + // E.g. we have seen cases where a proc macro can handle `a :: b` but not + // `a::b`. See #117433 for some examples. fn print_tts(&mut self, tts: &TokenStream, convert_dollar_crate: bool) { let mut iter = tts.trees().peekable(); while let Some(tt) = iter.next() { let spacing = self.print_tt(tt, convert_dollar_crate); if let Some(next) = iter.peek() { - // Should we print a space after `tt`? There are two guiding - // factors. - // - `spacing` is the more important and accurate one. Most - // tokens have good spacing information, and - // `Joint`/`JointHidden` get used a lot. - // - `space_between` is the backup. Code produced by proc - // macros has worse spacing information, with no - // `JointHidden` usage and too much `Alone` usage, which - // would result in over-spaced output such as - // `( x () , y . z )`. `space_between` avoids some of the - // excess whitespace. if spacing == Spacing::Alone && space_between(tt, next) { self.space(); } diff --git a/compiler/rustc_expand/src/mbe.rs b/compiler/rustc_expand/src/mbe.rs index 32d12c4fd0cc9..08d4a03945489 100644 --- a/compiler/rustc_expand/src/mbe.rs +++ b/compiler/rustc_expand/src/mbe.rs @@ -68,6 +68,8 @@ pub(crate) enum KleeneOp { /// `MetaVarExpr` are "first-class" token trees. Useful for parsing macros. #[derive(Debug, PartialEq, Encodable, Decodable)] enum TokenTree { + /// A token. Unlike `tokenstream::TokenTree::Token` this lacks a `Spacing`. + /// See the comments about `Spacing` in the `transcribe` function. Token(Token), /// A delimited sequence, e.g. `($e:expr)` (RHS) or `{ $e }` (LHS). Delimited(DelimSpan, DelimSpacing, Delimited), diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 3901b82eb52ec..8a084dcb4fe3a 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -253,8 +253,23 @@ pub(super) fn transcribe<'a>( mbe::TokenTree::MetaVar(mut sp, mut original_ident) => { // Find the matched nonterminal from the macro invocation, and use it to replace // the meta-var. + // + // We use `Spacing::Alone` everywhere here, because that's the conservative choice + // and spacing of declarative macros is tricky. E.g. in this macro: + // ``` + // macro_rules! idents { + // ($($a:ident,)*) => { stringify!($($a)*) } + // } + // ``` + // `$a` has no whitespace after it and will be marked `JointHidden`. If you then + // call `idents!(x,y,z,)`, each of `x`, `y`, and `z` will be marked as `Joint`. So + // if you choose to use `$x`'s spacing or the identifier's spacing, you'll end up + // producing "xyz", which is bad because it effectively merges tokens. + // `Spacing::Alone` is the safer option. Fortunately, `space_between` will avoid + // some of the unnecessary whitespace. let ident = MacroRulesNormalizedIdent::new(original_ident); if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) { + // njn: explain the use of alone here let tt = match cur_matched { MatchedSingle(ParseNtResult::Tt(tt)) => { // `tt`s are emitted into the output stream directly as "raw tokens", From ae49dbe707b50900d16bd8ecf8981e0c5534752b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 17 May 2024 14:43:59 +0200 Subject: [PATCH 11/12] Cleanup: Fix up some diagnostics --- compiler/rustc_infer/messages.ftl | 4 +-- compiler/rustc_lint/messages.ftl | 2 +- compiler/rustc_lint/src/lints.rs | 2 +- compiler/rustc_mir_build/messages.ftl | 23 ++++++++------- compiler/rustc_mir_build/src/errors.rs | 28 +++++++++++-------- .../pub/pub-reexport-priv-extern-crate.stderr | 5 ++-- .../safe-calls.stderr | 2 +- ...edition-2024-unsafe_op_in_unsafe_fn.stderr | 3 +- .../edition_2024_default.stderr | 3 +- .../in_2024_compatibility.stderr | 3 +- .../rfc-2585-unsafe_op_in_unsafe_fn.stderr | 12 ++++---- .../wrapping-unsafe-block-sugg.stderr | 17 +++++------ 12 files changed, 57 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl index 8f1c4ad462a67..fbe8d31370cc3 100644 --- a/compiler/rustc_infer/messages.ftl +++ b/compiler/rustc_infer/messages.ftl @@ -104,10 +104,10 @@ infer_compare_impl_item_obligation = ...so that the definition in impl matches t infer_consider_specifying_length = consider specifying the actual array length infer_data_flows = ...but data{$label_var1_exists -> [true] {" "}from `{$label_var1}` - *[false] -> {""} + *[false] {""} } flows{$label_var2_exists -> [true] {" "}into `{$label_var2}` - *[false] -> {""} + *[false] {""} } here infer_data_lifetime_flow = ...but data with one lifetime flows into the other here diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 6f6480a496413..8b1a9a12886e6 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -627,7 +627,7 @@ lint_pattern_in_foreign = patterns aren't allowed in foreign function declaratio .label = pattern not allowed in foreign function lint_private_extern_crate_reexport = - extern crate `{$ident}` is private, and cannot be re-exported (error E0365), consider declaring with `pub` + extern crate `{$ident}` is private, and cannot be re-exported, consider declaring with `pub` lint_proc_macro_back_compat = using an old version of `{$crate_name}` .note = older versions of the `{$crate_name}` crate will stop compiling in future versions of Rust; please update to `{$crate_name}` v{$fixed_version}, or switch to one of the `{$crate_name}` alternatives diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 3bd6faca37963..51f58e3f4e531 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2227,7 +2227,7 @@ pub struct MacroUseDeprecated; pub struct UnusedMacroUse; #[derive(LintDiagnostic)] -#[diag(lint_private_extern_crate_reexport)] +#[diag(lint_private_extern_crate_reexport, code = E0365)] pub struct PrivateExternCrateReexport { pub ident: Ident, } diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 0bb44dbb8706b..67e1e15defab4 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -335,12 +335,12 @@ mir_build_unsafe_fn_safe_body = an unsafe function restricts its caller, but its mir_build_unsafe_not_inherited = items do not inherit unsafety from separate enclosing items mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe = - borrow of layout constrained field with interior mutability is unsafe and requires unsafe block (error E0133) + borrow of layout constrained field with interior mutability is unsafe and requires unsafe block .note = references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values .label = borrow of layout constrained field with interior mutability mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe = - call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block (error E0133) + call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block .help = in order for the call to be safe, the context requires the following additional target {$missing_target_features_count -> [1] feature *[count] features @@ -355,48 +355,47 @@ mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe = .label = call to function with `#[target_feature]` mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe = - call to unsafe function `{$function}` is unsafe and requires unsafe block (error E0133) + call to unsafe function `{$function}` is unsafe and requires unsafe block .note = consult the function's documentation for information on how to avoid undefined behavior .label = call to unsafe function mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless = - call to unsafe function is unsafe and requires unsafe block (error E0133) + call to unsafe function is unsafe and requires unsafe block .note = consult the function's documentation for information on how to avoid undefined behavior .label = call to unsafe function mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe = - dereference of raw pointer is unsafe and requires unsafe block (error E0133) + dereference of raw pointer is unsafe and requires unsafe block .note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior .label = dereference of raw pointer mir_build_unsafe_op_in_unsafe_fn_extern_static_requires_unsafe = - use of extern static is unsafe and requires unsafe block (error E0133) + use of extern static is unsafe and requires unsafe block .note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior .label = use of extern static mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe = - initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe - block (error E0133) + initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe block .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior .label = initializing type with `rustc_layout_scalar_valid_range` attr mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe = - use of inline assembly is unsafe and requires unsafe block (error E0133) + use of inline assembly is unsafe and requires unsafe block .note = inline assembly is entirely unchecked and can cause undefined behavior .label = use of inline assembly mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe = - use of mutable static is unsafe and requires unsafe block (error E0133) + use of mutable static is unsafe and requires unsafe block .note = mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior .label = use of mutable static mir_build_unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe = - mutation of layout constrained field is unsafe and requires unsafe block (error E0133) + mutation of layout constrained field is unsafe and requires unsafe block .note = mutating layout constrained fields cannot statically be checked for valid values .label = mutation of layout constrained field mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe = - access to union field is unsafe and requires unsafe block (error E0133) + access to union field is unsafe and requires unsafe block .note = the field may not be properly initialized: using uninitialized data will cause undefined behavior .label = access to union field diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index e2a28467b8457..38e6c00add81e 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -21,7 +21,7 @@ pub struct UnconditionalRecursion { } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe, code = E0133)] #[note] pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { #[label] @@ -32,7 +32,7 @@ pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless, code = E0133)] #[note] pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { #[label] @@ -42,7 +42,7 @@ pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe, code = E0133)] #[note] pub struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { #[label] @@ -52,7 +52,7 @@ pub struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe, code = E0133)] #[note] pub struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { #[label] @@ -62,7 +62,7 @@ pub struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe, code = E0133)] #[note] pub struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { #[label] @@ -72,7 +72,7 @@ pub struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_extern_static_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_extern_static_requires_unsafe, code = E0133)] #[note] pub struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { #[label] @@ -82,7 +82,7 @@ pub struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe, code = E0133)] #[note] pub struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { #[label] @@ -92,7 +92,7 @@ pub struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe, code = E0133)] #[note] pub struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { #[label] @@ -102,7 +102,10 @@ pub struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe)] +#[diag( + mir_build_unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe, + code = E0133 +)] #[note] pub struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { #[label] @@ -112,7 +115,10 @@ pub struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe)] +#[diag( + mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe, + code = E0133, +)] pub struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { #[label] pub span: Span, @@ -121,7 +127,7 @@ pub struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe)] +#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe, code = E0133)] #[help] pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { #[label] diff --git a/tests/ui/pub/pub-reexport-priv-extern-crate.stderr b/tests/ui/pub/pub-reexport-priv-extern-crate.stderr index c7fadc6f92931..3fa5b0f9aef3e 100644 --- a/tests/ui/pub/pub-reexport-priv-extern-crate.stderr +++ b/tests/ui/pub/pub-reexport-priv-extern-crate.stderr @@ -22,7 +22,7 @@ note: the crate import `core` is defined here LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ -error: extern crate `core` is private, and cannot be re-exported (error E0365), consider declaring with `pub` +error[E0365]: extern crate `core` is private, and cannot be re-exported, consider declaring with `pub` --> $DIR/pub-reexport-priv-extern-crate.rs:2:9 | LL | pub use core as reexported_core; @@ -34,4 +34,5 @@ LL | pub use core as reexported_core; error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0603`. +Some errors have detailed explanations: E0365, E0603. +For more information about an error, try `rustc --explain E0365`. diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr index aa660db38679c..537819ab8595c 100644 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr +++ b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr @@ -91,7 +91,7 @@ LL | const _: () = sse2_and_fxsr(); = help: in order for the call to be safe, the context requires the following additional target features: sse2 and fxsr = note: the fxsr and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]` -error: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe block (error E0133) +error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe block --> $DIR/safe-calls.rs:70:5 | LL | sse2(); diff --git a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr index 2eb1754392e1a..fe12dd72d9ebe 100644 --- a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr +++ b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr @@ -1,4 +1,4 @@ -warning: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) +warning[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block --> $DIR/edition-2024-unsafe_op_in_unsafe_fn.rs:10:5 | LL | unsf(); @@ -15,3 +15,4 @@ LL | unsafe fn foo() { warning: 1 warning emitted +For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr index e6d1d4e5cc780..05f36ab47cb56 100644 --- a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr +++ b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr @@ -1,4 +1,4 @@ -warning: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) +warning[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block --> $DIR/edition_2024_default.rs:13:5 | LL | unsf(); @@ -15,3 +15,4 @@ LL | unsafe fn foo() { warning: 1 warning emitted +For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/in_2024_compatibility.stderr b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/in_2024_compatibility.stderr index 5092c1e689d67..3f97199458da4 100644 --- a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/in_2024_compatibility.stderr +++ b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/in_2024_compatibility.stderr @@ -1,4 +1,4 @@ -error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) +error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block --> $DIR/in_2024_compatibility.rs:7:5 | LL | unsf(); @@ -20,3 +20,4 @@ LL | #![deny(rust_2024_compatibility)] error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/rfc-2585-unsafe_op_in_unsafe_fn.stderr b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/rfc-2585-unsafe_op_in_unsafe_fn.stderr index 4bc604a110ea1..1f80342566ca3 100644 --- a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/rfc-2585-unsafe_op_in_unsafe_fn.stderr +++ b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/rfc-2585-unsafe_op_in_unsafe_fn.stderr @@ -1,4 +1,4 @@ -error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) +error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:9:5 | LL | unsf(); @@ -17,7 +17,7 @@ note: the lint level is defined here LL | #![deny(unsafe_op_in_unsafe_fn)] | ^^^^^^^^^^^^^^^^^^^^^^ -error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) +error[E0133]: dereference of raw pointer is unsafe and requires unsafe block --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:11:5 | LL | *PTR; @@ -26,7 +26,7 @@ LL | *PTR; = note: for more information, see issue #71668 = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior -error: use of mutable static is unsafe and requires unsafe block (error E0133) +error[E0133]: use of mutable static is unsafe and requires unsafe block --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:13:5 | LL | VOID = (); @@ -47,7 +47,7 @@ note: the lint level is defined here LL | #![deny(unused_unsafe)] | ^^^^^^^^^^^^^ -error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) +error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:24:5 | LL | unsf(); @@ -67,7 +67,7 @@ LL | #[deny(warnings)] | ^^^^^^^^ = note: `#[deny(unsafe_op_in_unsafe_fn)]` implied by `#[deny(warnings)]` -error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) +error[E0133]: dereference of raw pointer is unsafe and requires unsafe block --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:5 | LL | *PTR; @@ -76,7 +76,7 @@ LL | *PTR; = note: for more information, see issue #71668 = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior -error: use of mutable static is unsafe and requires unsafe block (error E0133) +error[E0133]: use of mutable static is unsafe and requires unsafe block --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:28:5 | LL | VOID = (); diff --git a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/wrapping-unsafe-block-sugg.stderr b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/wrapping-unsafe-block-sugg.stderr index b9f5969474d00..1ce22ecfdc796 100644 --- a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/wrapping-unsafe-block-sugg.stderr +++ b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/wrapping-unsafe-block-sugg.stderr @@ -1,4 +1,4 @@ -error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) +error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block --> $DIR/wrapping-unsafe-block-sugg.rs:13:5 | LL | unsf(); @@ -17,7 +17,7 @@ note: the lint level is defined here LL | #![deny(unsafe_op_in_unsafe_fn)] | ^^^^^^^^^^^^^^^^^^^^^^ -error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) +error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block --> $DIR/wrapping-unsafe-block-sugg.rs:17:5 | LL | unsf(); @@ -26,7 +26,7 @@ LL | unsf(); = note: for more information, see issue #71668 = note: consult the function's documentation for information on how to avoid undefined behavior -error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) +error[E0133]: dereference of raw pointer is unsafe and requires unsafe block --> $DIR/wrapping-unsafe-block-sugg.rs:25:13 | LL | let y = *x; @@ -40,7 +40,7 @@ note: an unsafe function restricts its caller, but its body is safe by default LL | pub unsafe fn bar(x: *const i32) -> i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) +error[E0133]: dereference of raw pointer is unsafe and requires unsafe block --> $DIR/wrapping-unsafe-block-sugg.rs:29:9 | LL | y + *x @@ -49,7 +49,7 @@ LL | y + *x = note: for more information, see issue #71668 = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior -error: use of mutable static is unsafe and requires unsafe block (error E0133) +error[E0133]: use of mutable static is unsafe and requires unsafe block --> $DIR/wrapping-unsafe-block-sugg.rs:38:13 | LL | let y = BAZ; @@ -63,7 +63,7 @@ note: an unsafe function restricts its caller, but its body is safe by default LL | pub unsafe fn baz() -> i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of mutable static is unsafe and requires unsafe block (error E0133) +error[E0133]: use of mutable static is unsafe and requires unsafe block --> $DIR/wrapping-unsafe-block-sugg.rs:42:9 | LL | y + BAZ @@ -72,7 +72,7 @@ LL | y + BAZ = note: for more information, see issue #71668 = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior -error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) +error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block --> $DIR/wrapping-unsafe-block-sugg.rs:48:36 | LL | macro_rules! unsafe_macro { () => (unsf()) } @@ -90,7 +90,7 @@ LL | pub unsafe fn unsafe_in_macro() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `unsafe_macro` (in Nightly builds, run with -Z macro-backtrace for more info) -error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) +error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block --> $DIR/wrapping-unsafe-block-sugg.rs:48:36 | LL | macro_rules! unsafe_macro { () => (unsf()) } @@ -105,3 +105,4 @@ LL | unsafe_macro!(); error: aborting due to 8 previous errors +For more information about this error, try `rustc --explain E0133`. From 07b7cd62c70ef6ec111e9a7182cb83ec0209460e Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 17 Mar 2024 15:46:40 -0700 Subject: [PATCH 12/12] Add some tests for public-private dependencies. --- .../auxiliary/diamond_priv_dep.rs | 9 +++ .../pub-priv-dep/auxiliary/diamond_pub_dep.rs | 9 +++ .../pub-priv-dep/auxiliary/indirect1.rs | 4 ++ .../pub-priv-dep/auxiliary/indirect2.rs | 4 ++ tests/ui/privacy/pub-priv-dep/auxiliary/pm.rs | 22 ++++++ .../pub-priv-dep/auxiliary/priv_dep.rs | 9 +++ .../pub-priv-dep/auxiliary/reexport.rs | 5 ++ .../privacy/pub-priv-dep/auxiliary/shared.rs | 1 + tests/ui/privacy/pub-priv-dep/diamond_deps.rs | 48 +++++++++++++ .../privacy/pub-priv-dep/diamond_deps.stderr | 14 ++++ tests/ui/privacy/pub-priv-dep/pub-priv1.rs | 67 ++++++++++++++++++- .../ui/privacy/pub-priv-dep/pub-priv1.stderr | 62 +++++++++++++++-- .../pub-priv-dep/reexport_from_priv.rs | 15 +++++ .../pub-priv-dep/shared_both_private.rs | 32 +++++++++ .../pub-priv-dep/shared_direct_private.rs | 39 +++++++++++ .../privacy/pub-priv-dep/shared_indirect.rs | 29 ++++++++ 16 files changed, 360 insertions(+), 9 deletions(-) create mode 100644 tests/ui/privacy/pub-priv-dep/auxiliary/diamond_priv_dep.rs create mode 100644 tests/ui/privacy/pub-priv-dep/auxiliary/diamond_pub_dep.rs create mode 100644 tests/ui/privacy/pub-priv-dep/auxiliary/indirect1.rs create mode 100644 tests/ui/privacy/pub-priv-dep/auxiliary/indirect2.rs create mode 100644 tests/ui/privacy/pub-priv-dep/auxiliary/pm.rs create mode 100644 tests/ui/privacy/pub-priv-dep/auxiliary/reexport.rs create mode 100644 tests/ui/privacy/pub-priv-dep/auxiliary/shared.rs create mode 100644 tests/ui/privacy/pub-priv-dep/diamond_deps.rs create mode 100644 tests/ui/privacy/pub-priv-dep/diamond_deps.stderr create mode 100644 tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs create mode 100644 tests/ui/privacy/pub-priv-dep/shared_both_private.rs create mode 100644 tests/ui/privacy/pub-priv-dep/shared_direct_private.rs create mode 100644 tests/ui/privacy/pub-priv-dep/shared_indirect.rs diff --git a/tests/ui/privacy/pub-priv-dep/auxiliary/diamond_priv_dep.rs b/tests/ui/privacy/pub-priv-dep/auxiliary/diamond_priv_dep.rs new file mode 100644 index 0000000000000..ed76815a6ac8e --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/auxiliary/diamond_priv_dep.rs @@ -0,0 +1,9 @@ +//@ aux-crate:shared=shared.rs + +extern crate shared; + +pub use shared::Shared; + +pub struct SharedInType { + pub f: Shared +} diff --git a/tests/ui/privacy/pub-priv-dep/auxiliary/diamond_pub_dep.rs b/tests/ui/privacy/pub-priv-dep/auxiliary/diamond_pub_dep.rs new file mode 100644 index 0000000000000..ed76815a6ac8e --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/auxiliary/diamond_pub_dep.rs @@ -0,0 +1,9 @@ +//@ aux-crate:shared=shared.rs + +extern crate shared; + +pub use shared::Shared; + +pub struct SharedInType { + pub f: Shared +} diff --git a/tests/ui/privacy/pub-priv-dep/auxiliary/indirect1.rs b/tests/ui/privacy/pub-priv-dep/auxiliary/indirect1.rs new file mode 100644 index 0000000000000..0e4a73c7fc011 --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/auxiliary/indirect1.rs @@ -0,0 +1,4 @@ +//@ aux-crate:priv:indirect2=indirect2.rs +//@ compile-flags: -Zunstable-options + +extern crate indirect2; diff --git a/tests/ui/privacy/pub-priv-dep/auxiliary/indirect2.rs b/tests/ui/privacy/pub-priv-dep/auxiliary/indirect2.rs new file mode 100644 index 0000000000000..5f6b289eb1414 --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/auxiliary/indirect2.rs @@ -0,0 +1,4 @@ +//@ aux-crate:shared=shared.rs + +// This is public. +extern crate shared; diff --git a/tests/ui/privacy/pub-priv-dep/auxiliary/pm.rs b/tests/ui/privacy/pub-priv-dep/auxiliary/pm.rs new file mode 100644 index 0000000000000..9e2aa898afe8d --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/auxiliary/pm.rs @@ -0,0 +1,22 @@ +//@ force-host +//@ no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro] +pub fn fn_like(input: TokenStream) -> TokenStream { + "".parse().unwrap() +} + +#[proc_macro_derive(PmDerive)] +pub fn pm_derive(item: TokenStream) -> TokenStream { + "".parse().unwrap() +} + +#[proc_macro_attribute] +pub fn pm_attr(attr: TokenStream, item: TokenStream) -> TokenStream { + "".parse().unwrap() +} diff --git a/tests/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs b/tests/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs index e7afeb84fb4f4..4eeecdc056972 100644 --- a/tests/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs +++ b/tests/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs @@ -1,2 +1,11 @@ pub struct OtherType; pub trait OtherTrait {} + +#[macro_export] +macro_rules! m { + () => {}; +} + +pub enum E { + V1 +} diff --git a/tests/ui/privacy/pub-priv-dep/auxiliary/reexport.rs b/tests/ui/privacy/pub-priv-dep/auxiliary/reexport.rs new file mode 100644 index 0000000000000..0655e3ae2cfdb --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/auxiliary/reexport.rs @@ -0,0 +1,5 @@ +//@ aux-crate:shared=shared.rs + +extern crate shared; + +pub use shared::Shared; diff --git a/tests/ui/privacy/pub-priv-dep/auxiliary/shared.rs b/tests/ui/privacy/pub-priv-dep/auxiliary/shared.rs new file mode 100644 index 0000000000000..efc4daa7befb8 --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/auxiliary/shared.rs @@ -0,0 +1 @@ +pub struct Shared; diff --git a/tests/ui/privacy/pub-priv-dep/diamond_deps.rs b/tests/ui/privacy/pub-priv-dep/diamond_deps.rs new file mode 100644 index 0000000000000..0e1f6f36bc8cc --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/diamond_deps.rs @@ -0,0 +1,48 @@ +//@ aux-crate:priv:diamond_priv_dep=diamond_priv_dep.rs +//@ aux-crate:diamond_pub_dep=diamond_pub_dep.rs +//@ compile-flags: -Zunstable-options + +// A diamond dependency: +// +// diamond_reepxort +// /\ +// (public) / \ (PRIVATE) +// / \ +// diamond_pub_dep diamond_priv_dep +// \ / +// (public) \ / (public) +// \/ +// shared +// +// Where the pub and private crates reexport something from the shared crate. +// +// Checks the behavior when the same shared item appears in the public API, +// depending on whether it comes from the public side or the private side. +// +// NOTE: compiletest does not support deduplicating shared dependencies. +// However, it should work well enough for this test, the only downside is +// that diamond_shared gets built twice. + +#![crate_type = "lib"] +#![deny(exported_private_dependencies)] + +extern crate diamond_priv_dep; +extern crate diamond_pub_dep; + +// FIXME: This should trigger. +pub fn leaks_priv() -> diamond_priv_dep::Shared { + diamond_priv_dep::Shared +} + +pub fn leaks_pub() -> diamond_pub_dep::Shared { + diamond_pub_dep::Shared +} + +pub struct PrivInStruct { + pub f: diamond_priv_dep::SharedInType +//~^ ERROR type `diamond_priv_dep::SharedInType` from private dependency 'diamond_priv_dep' in public interface +} + +pub struct PubInStruct { + pub f: diamond_pub_dep::SharedInType +} diff --git a/tests/ui/privacy/pub-priv-dep/diamond_deps.stderr b/tests/ui/privacy/pub-priv-dep/diamond_deps.stderr new file mode 100644 index 0000000000000..8a6d35a747b63 --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/diamond_deps.stderr @@ -0,0 +1,14 @@ +error: type `diamond_priv_dep::SharedInType` from private dependency 'diamond_priv_dep' in public interface + --> $DIR/diamond_deps.rs:42:5 + | +LL | pub f: diamond_priv_dep::SharedInType + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/diamond_deps.rs:27:9 + | +LL | #![deny(exported_private_dependencies)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/privacy/pub-priv-dep/pub-priv1.rs b/tests/ui/privacy/pub-priv-dep/pub-priv1.rs index f26dbb47ba5e9..112eaf528be27 100644 --- a/tests/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/tests/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -1,12 +1,20 @@ //@ aux-crate:priv:priv_dep=priv_dep.rs //@ aux-build:pub_dep.rs +//@ aux-crate:priv:pm=pm.rs //@ compile-flags: -Zunstable-options + +// Basic behavior check of exported_private_dependencies from either a public +// dependency or a private one. + #![deny(exported_private_dependencies)] // This crate is a private dependency -extern crate priv_dep; +// FIXME: This should trigger. +pub extern crate priv_dep; // This crate is a public dependency extern crate pub_dep; +// This crate is a private dependency +extern crate pm; use priv_dep::{OtherTrait, OtherType}; use pub_dep::PubType; @@ -25,7 +33,10 @@ pub struct PublicType { } impl PublicType { - pub fn pub_fn(param: OtherType) {} + pub fn pub_fn_param(param: OtherType) {} + //~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface + + pub fn pub_fn_return() -> OtherType { OtherType } //~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface fn priv_fn(param: OtherType) {} @@ -36,9 +47,61 @@ pub trait MyPubTrait { } //~^^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface +pub trait WithSuperTrait: OtherTrait {} +//~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface + +pub trait PubLocalTraitWithAssoc { + type X; +} + +pub struct PrivateAssoc; +impl PubLocalTraitWithAssoc for PrivateAssoc { + type X = OtherType; +//~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface +} + +pub fn in_bounds(x: T) { unimplemented!() } +//~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface + +pub fn private_in_generic() -> std::num::Saturating { unimplemented!() } +//~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface + +pub static STATIC: OtherType = OtherType; +//~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface + +pub const CONST: OtherType = OtherType; +//~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface + +pub type Alias = OtherType; +//~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface + +pub struct PublicWithPrivateImpl; + +// FIXME: This should trigger. +// See https://github.com/rust-lang/rust/issues/71043 +impl OtherTrait for PublicWithPrivateImpl {} + +pub trait PubTraitOnPrivate {} + +// FIXME: This should trigger. +// See https://github.com/rust-lang/rust/issues/71043 +impl PubTraitOnPrivate for OtherType {} + pub struct AllowedPrivType { #[allow(exported_private_dependencies)] pub allowed: OtherType, } +// FIXME: This should trigger. +pub use priv_dep::m; +// FIXME: This should trigger. +pub use pm::fn_like; +// FIXME: This should trigger. +pub use pm::PmDerive; +// FIXME: This should trigger. +pub use pm::pm_attr; + +// FIXME: This should trigger. +pub use priv_dep::E::V1; + fn main() {} diff --git a/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr b/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr index e62a440d8f568..53d461a5774a0 100644 --- a/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -1,26 +1,74 @@ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:21:5 + --> $DIR/pub-priv1.rs:29:5 | LL | pub field: OtherType, | ^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/pub-priv1.rs:4:9 + --> $DIR/pub-priv1.rs:9:9 | LL | #![deny(exported_private_dependencies)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:28:5 + --> $DIR/pub-priv1.rs:36:5 | -LL | pub fn pub_fn(param: OtherType) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub fn pub_fn_param(param: OtherType) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: type `OtherType` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:39:5 + | +LL | pub fn pub_fn_return() -> OtherType { OtherType } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:35:5 + --> $DIR/pub-priv1.rs:46:5 | LL | type Foo: OtherTrait; | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: trait `OtherTrait` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:50:1 + | +LL | pub trait WithSuperTrait: OtherTrait {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: type `OtherType` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:59:5 + | +LL | type X = OtherType; + | ^^^^^^ + +error: trait `OtherTrait` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:63:1 + | +LL | pub fn in_bounds(x: T) { unimplemented!() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: type `OtherType` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:66:1 + | +LL | pub fn private_in_generic() -> std::num::Saturating { unimplemented!() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: type `OtherType` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:69:1 + | +LL | pub static STATIC: OtherType = OtherType; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: type `OtherType` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:72:1 + | +LL | pub const CONST: OtherType = OtherType; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: type `OtherType` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:75:1 + | +LL | pub type Alias = OtherType; + | ^^^^^^^^^^^^^^ + +error: aborting due to 11 previous errors diff --git a/tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs b/tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs new file mode 100644 index 0000000000000..3c6e9825e7288 --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs @@ -0,0 +1,15 @@ +//@ aux-crate:priv:reexport=reexport.rs +//@ compile-flags: -Zunstable-options +//@ check-pass + +// Checks the behavior of a reexported item from a private dependency. + +#![crate_type = "lib"] +#![deny(exported_private_dependencies)] + +extern crate reexport; + +// FIXME: This should trigger. +pub fn leaks_priv() -> reexport::Shared { + reexport::Shared +} diff --git a/tests/ui/privacy/pub-priv-dep/shared_both_private.rs b/tests/ui/privacy/pub-priv-dep/shared_both_private.rs new file mode 100644 index 0000000000000..20a4b85c01e8d --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/shared_both_private.rs @@ -0,0 +1,32 @@ +//@ aux-crate:priv:shared=shared.rs +//@ aux-crate:reexport=reexport.rs +//@ compile-flags: -Zunstable-options +//@ check-pass + +// A shared dependency, where a private dependency reexports a public dependency. +// +// shared_both_private +// /\ +// (PRIVATE) / | (PRIVATE) +// / | +// reexport | +// \ | +// (public) \ / +// \/ +// shared + +#![crate_type = "lib"] +#![deny(exported_private_dependencies)] + +extern crate shared; +extern crate reexport; + +// FIXME: This should trigger. +pub fn leaks_priv() -> shared::Shared { + shared::Shared +} + +// FIXME: This should trigger. +pub fn leaks_priv_reexport() -> reexport::Shared { + reexport::Shared +} diff --git a/tests/ui/privacy/pub-priv-dep/shared_direct_private.rs b/tests/ui/privacy/pub-priv-dep/shared_direct_private.rs new file mode 100644 index 0000000000000..b329a7acb5834 --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/shared_direct_private.rs @@ -0,0 +1,39 @@ +//@ aux-crate:priv:shared=shared.rs +//@ aux-crate:reexport=reexport.rs +//@ compile-flags: -Zunstable-options +//@ check-pass + +// A shared dependency, where the public side reexports the same item as a +// direct private dependency. +// +// shared_direct_private +// /\ +// (public) / | (PRIVATE) +// / | +// reexport | +// \ | +// (public) \ / +// \/ +// shared +// + +#![crate_type = "lib"] +#![deny(exported_private_dependencies)] + +extern crate shared; +extern crate reexport; + +// FIXME: Should this trigger? +// +// One could make an argument that I said I want "reexport" to be public, and +// since "reexport" says "shared_direct_private" is public, then it should +// transitively be public for me. However, as written, this is explicitly +// referring to a dependency that is marked "private", which I think is +// confusing. +pub fn leaks_priv() -> shared::Shared { + shared::Shared +} + +pub fn leaks_pub() -> reexport::Shared { + reexport::Shared +} diff --git a/tests/ui/privacy/pub-priv-dep/shared_indirect.rs b/tests/ui/privacy/pub-priv-dep/shared_indirect.rs new file mode 100644 index 0000000000000..34b624b4a1a40 --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/shared_indirect.rs @@ -0,0 +1,29 @@ +//@ 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. +// +// shared_indirect +// /\ +// (PRIVATE) / | (PRIVATE) +// / | +// indirect1 | | +// (PRIVATE) | | +// indirect2 | | +// \ | +// (public) \ / +// \/ +// shared + +#![crate_type = "lib"] +#![deny(exported_private_dependencies)] + +extern crate shared; +extern crate indirect1; + +// FIXME: This should trigger. +pub fn leaks_priv() -> shared::Shared { + shared::Shared +}