Auto merge of #126345 - compiler-errors:rollup-lue8u92, r=compiler-errors

Rollup of 8 pull requests

Successful merges:

 - #125869 (Add `target_env = "p1"` to the `wasm32-wasip1` target)
 - #126019 (Add TODO comment to unsafe env modification)
 - #126036 (Migrate `run-make/short-ice` to `rmake`)
 - #126276 (Detect pub structs never constructed even though they impl pub trait with assoc constants)
 - #126282 (Ensure self-contained linker is only enabled on dev/nightly )
 - #126317 (Avoid a bunch of booleans in favor of Result<(), ErrorGuaranteed> as that more robustly proves that an error has been emitted)
 - #126324 (Adjust LoongArch64 data layouts for LLVM update)
 - #126340 (Fix outdated predacates_of.rs comments)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-06-12 20:48:06 +00:00
commit 8337ba9189
32 changed files with 251 additions and 113 deletions

View File

@ -142,6 +142,14 @@ pub unsafe fn create_module<'ll>(
}
}
if llvm_version < (19, 0, 0) {
if sess.target.arch == "loongarch64" {
// LLVM 19 updates the LoongArch64 data layout.
// See https://github.com/llvm/llvm-project/pull/93814
target_data_layout = target_data_layout.replace("-n32:64", "-n64");
}
}
// Ensure the data-layout values hardcoded remain the defaults.
{
let tm = crate::back::write::create_informational_target_machine(tcx.sess);

View File

@ -169,12 +169,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
predicates.insert((trait_ref.upcast(tcx), tcx.def_span(def_id)));
}
// Collect the predicates that were written inline by the user on each
// type parameter (e.g., `<T: Foo>`). Also add `ConstArgHasType` predicates
// for each const parameter.
// Add implicit predicates that should be treated as if the user has written them,
// including the implicit `T: Sized` for all generic parameters, and `ConstArgHasType`
// for const params.
for param in hir_generics.params {
match param.kind {
// We already dealt with early bound lifetimes above.
GenericParamKind::Lifetime { .. } => (),
GenericParamKind::Type { .. } => {
let param_ty = icx.lowerer().lower_ty_param(param.hir_id);
@ -204,7 +203,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
}
trace!(?predicates);
// Add in the bounds that appear in the where-clause.
// Add inline `<T: Foo>` bounds and bounds in the where clause.
for predicate in hir_generics.predicates {
match predicate {
hir::WherePredicate::BoundPredicate(bound_pred) => {

View File

@ -1342,14 +1342,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Ok(method)
}
Err(error) => {
if segment.ident.name != kw::Empty {
if let Some(err) =
self.report_method_error(expr.hir_id, rcvr_t, error, expected, false)
{
err.emit();
}
if segment.ident.name == kw::Empty {
span_bug!(rcvr.span, "empty method name")
} else {
Err(self.report_method_error(expr.hir_id, rcvr_t, error, expected, false))
}
Err(())
}
};

View File

@ -660,8 +660,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
})
}
pub(crate) fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
let ty_error = Ty::new_misc_error(self.tcx);
pub(crate) fn err_args(&self, len: usize, guar: ErrorGuaranteed) -> Vec<Ty<'tcx>> {
let ty_error = Ty::new_error(self.tcx, guar);
vec![ty_error; len]
}
@ -846,15 +846,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
if item_name.name != kw::Empty {
if let Some(e) = self.report_method_error(
self.report_method_error(
hir_id,
ty.normalized,
error,
Expectation::NoExpectation,
trait_missing_method && span.edition().at_least_rust_2021(), // emits missing method for trait only after edition 2021
) {
e.emit();
}
);
}
result

View File

@ -113,17 +113,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
sp: Span,
expr: &'tcx hir::Expr<'tcx>,
method: Result<MethodCallee<'tcx>, ()>,
method: Result<MethodCallee<'tcx>, ErrorGuaranteed>,
args_no_rcvr: &'tcx [hir::Expr<'tcx>],
tuple_arguments: TupleArgumentsFlag,
expected: Expectation<'tcx>,
) -> Ty<'tcx> {
let has_error = match method {
Ok(method) => method.args.references_error() || method.sig.references_error(),
Err(_) => true,
Ok(method) => method.args.error_reported().and(method.sig.error_reported()),
Err(guar) => Err(guar),
};
if has_error {
let err_inputs = self.err_args(args_no_rcvr.len());
if let Err(guar) = has_error {
let err_inputs = self.err_args(args_no_rcvr.len(), guar);
let err_inputs = match tuple_arguments {
DontTupleArguments => err_inputs,
@ -140,7 +140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
tuple_arguments,
method.ok().map(|method| method.def_id),
);
return Ty::new_misc_error(self.tcx);
return Ty::new_error(self.tcx, guar);
}
let method = method.unwrap();
@ -237,7 +237,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => {
// Otherwise, there's a mismatch, so clear out what we're expecting, and set
// our input types to err_args so we don't blow up the error messages
struct_span_code_err!(
let guar = struct_span_code_err!(
tcx.dcx(),
call_span,
E0059,
@ -245,7 +245,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
for the function trait is neither a tuple nor unit"
)
.emit();
(self.err_args(provided_args.len()), None)
(self.err_args(provided_args.len(), guar), None)
}
}
} else {

View File

@ -33,7 +33,7 @@ use rustc_middle::ty::IsSuggestable;
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::def_id::DefIdSet;
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{edit_distance, ExpnKind, FileName, MacroKind, Span};
use rustc_span::{edit_distance, ErrorGuaranteed, ExpnKind, FileName, MacroKind, Span};
use rustc_span::{Symbol, DUMMY_SP};
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedNote;
@ -192,7 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
error: MethodError<'tcx>,
expected: Expectation<'tcx>,
trait_missing_method: bool,
) -> Option<Diag<'_>> {
) -> ErrorGuaranteed {
let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) {
hir::Node::Expr(&hir::Expr {
kind: hir::ExprKind::MethodCall(segment, rcvr, args, _),
@ -226,8 +226,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
// Avoid suggestions when we don't know what's going on.
if rcvr_ty.references_error() {
return None;
if let Err(guar) = rcvr_ty.error_reported() {
return guar;
}
match error {
@ -265,7 +265,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&mut sources,
Some(sugg_span),
);
err.emit();
return err.emit();
}
MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => {
@ -286,7 +286,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.unwrap_or_else(|| self.tcx.def_span(def_id));
err.span_label(sp, format!("private {kind} defined here"));
self.suggest_valid_traits(&mut err, item_name, out_of_scope_traits, true);
err.emit();
return err.emit();
}
MethodError::IllegalSizedBound { candidates, needs_mut, bound_span, self_expr } => {
@ -343,12 +343,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
}
err.emit();
return err.emit();
}
MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"),
}
None
}
fn suggest_missing_writer(&self, rcvr_ty: Ty<'tcx>, rcvr_expr: &hir::Expr<'tcx>) -> Diag<'_> {
@ -564,7 +563,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
pub fn report_no_match_method_error(
fn report_no_match_method_error(
&self,
mut span: Span,
rcvr_ty: Ty<'tcx>,
@ -576,7 +575,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
no_match_data: &mut NoMatchData<'tcx>,
expected: Expectation<'tcx>,
trait_missing_method: bool,
) -> Option<Diag<'_>> {
) -> ErrorGuaranteed {
let mode = no_match_data.mode;
let tcx = self.tcx;
let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty);
@ -608,14 +607,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// We could pass the file for long types into these two, but it isn't strictly necessary
// given how targeted they are.
if self.suggest_wrapping_range_with_parens(
if let Err(guar) = self.report_failed_method_call_on_range_end(
tcx,
rcvr_ty,
source,
span,
item_name,
&short_ty_str,
) || self.suggest_constraining_numerical_ty(
) {
return guar;
}
if let Err(guar) = self.report_failed_method_call_on_numerical_infer_var(
tcx,
rcvr_ty,
source,
@ -624,7 +626,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
item_name,
&short_ty_str,
) {
return None;
return guar;
}
span = item_name.span;
@ -881,7 +883,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
vec![(span.shrink_to_lo(), format!("into_iter()."))],
Applicability::MaybeIncorrect,
);
return Some(err);
return err.emit();
} else if !unsatisfied_predicates.is_empty() && matches!(rcvr_ty.kind(), ty::Param(_)) {
// We special case the situation where we are looking for `_` in
// `<TypeParam as _>::method` because otherwise the machinery will look for blanket
@ -1606,7 +1608,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
Some(err)
err.emit()
}
/// If an appropriate error source is not found, check method chain for possible candidates
@ -2251,7 +2253,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Suggest possible range with adding parentheses, for example:
/// when encountering `0..1.map(|i| i + 1)` suggest `(0..1).map(|i| i + 1)`.
fn suggest_wrapping_range_with_parens(
fn report_failed_method_call_on_range_end(
&self,
tcx: TyCtxt<'tcx>,
actual: Ty<'tcx>,
@ -2259,7 +2261,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: Span,
item_name: Ident,
ty_str: &str,
) -> bool {
) -> Result<(), ErrorGuaranteed> {
if let SelfSource::MethodCall(expr) = source {
for (_, parent) in tcx.hir().parent_iter(expr.hir_id).take(5) {
if let Node::Expr(parent_expr) = parent {
@ -2316,7 +2318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
if pick.is_ok() {
let range_span = parent_expr.span.with_hi(expr.span.hi());
tcx.dcx().emit_err(errors::MissingParenthesesInRange {
return Err(tcx.dcx().emit_err(errors::MissingParenthesesInRange {
span,
ty_str: ty_str.to_string(),
method_name: item_name.as_str().to_string(),
@ -2325,16 +2327,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
left: range_span.shrink_to_lo(),
right: range_span.shrink_to_hi(),
}),
});
return true;
}));
}
}
}
}
false
Ok(())
}
fn suggest_constraining_numerical_ty(
fn report_failed_method_call_on_numerical_infer_var(
&self,
tcx: TyCtxt<'tcx>,
actual: Ty<'tcx>,
@ -2343,7 +2344,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
item_kind: &str,
item_name: Ident,
ty_str: &str,
) -> bool {
) -> Result<(), ErrorGuaranteed> {
let found_candidate = all_traits(self.tcx)
.into_iter()
.any(|info| self.associated_value(info.def_id, item_name).is_some());
@ -2447,10 +2448,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
_ => {}
}
err.emit();
return true;
return Err(err.emit());
}
false
Ok(())
}
/// For code `rect::area(...)`,

View File

@ -8,7 +8,7 @@ edition = "2021"
tracing = "0.1.28"
tracing-core = "=0.1.30" # FIXME(Nilstrieb) tracing has a deadlock: https://github.com/tokio-rs/tracing/issues/2635
tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
tracing-tree = "0.3.0"
tracing-tree = "0.3.1"
# tidy-alphabetical-end
[dev-dependencies]

View File

@ -58,6 +58,7 @@ pub struct LoggerConfig {
pub verbose_thread_ids: Result<String, VarError>,
pub backtrace: Result<String, VarError>,
pub wraptree: Result<String, VarError>,
pub lines: Result<String, VarError>,
}
impl LoggerConfig {
@ -69,6 +70,7 @@ impl LoggerConfig {
verbose_thread_ids: env::var(format!("{env}_THREAD_IDS")),
backtrace: env::var(format!("{env}_BACKTRACE")),
wraptree: env::var(format!("{env}_WRAPTREE")),
lines: env::var(format!("{env}_LINES")),
}
}
}
@ -101,6 +103,11 @@ pub fn init_logger(cfg: LoggerConfig) -> Result<(), Error> {
Err(_) => false,
};
let lines = match cfg.lines {
Ok(v) => &v == "1",
Err(_) => false,
};
let mut layer = tracing_tree::HierarchicalLayer::default()
.with_writer(io::stderr)
.with_ansi(color_logs)
@ -108,6 +115,7 @@ pub fn init_logger(cfg: LoggerConfig) -> Result<(), Error> {
.with_verbose_exit(verbose_entry_exit)
.with_verbose_entry(verbose_entry_exit)
.with_indent_amount(2)
.with_indent_lines(lines)
.with_thread_ids(verbose_thread_ids)
.with_thread_names(verbose_thread_ids);

View File

@ -97,6 +97,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
if !span.at_least_rust_2024()
&& self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) =>
{
let sm = self.tcx.sess.source_map();
self.tcx.emit_node_span_lint(
DEPRECATED_SAFE,
self.hir_context,
@ -105,6 +106,8 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
span,
function: with_no_trimmed_paths!(self.tcx.def_path_str(id)),
sub: CallToDeprecatedSafeFnRequiresUnsafeSub {
indent: sm.indentation_before(span).unwrap_or_default(),
start_of_line: sm.span_extend_to_line(span).shrink_to_lo(),
left: span.shrink_to_lo(),
right: span.shrink_to_hi(),
},

View File

@ -33,6 +33,11 @@ pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafe {
#[derive(Subdiagnostic)]
#[multipart_suggestion(mir_build_suggestion, applicability = "machine-applicable")]
pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafeSub {
pub(crate) indent: String,
#[suggestion_part(
code = "{indent}// TODO: Audit that the environment access only happens in single-threaded code.\n" // ignore-tidy-todo
)]
pub(crate) start_of_line: Span,
#[suggestion_part(code = "unsafe {{ ")]
pub(crate) left: Span,
#[suggestion_part(code = " }}")]

View File

@ -472,7 +472,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
&& let ItemKind::Impl(impl_ref) =
self.tcx.hir().expect_item(local_impl_id).kind
{
if matches!(trait_item.kind, hir::TraitItemKind::Fn(..))
if !matches!(trait_item.kind, hir::TraitItemKind::Type(..))
&& !ty_ref_to_pub_struct(self.tcx, impl_ref.self_ty)
.ty_and_all_fields_are_public
{
@ -802,7 +802,7 @@ fn check_item<'tcx>(
// And we access the Map here to get HirId from LocalDefId
for local_def_id in local_def_ids {
// check the function may construct Self
let mut may_construct_self = true;
let mut may_construct_self = false;
if let Some(fn_sig) =
tcx.hir().fn_sig_by_hir_id(tcx.local_def_id_to_hir_id(local_def_id))
{

View File

@ -10,7 +10,7 @@ pub fn target() -> Target {
std: None,
},
pointer_width: 64,
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(),
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
arch: "loongarch64".into(),
options: TargetOptions {
cpu: "generic".into(),

View File

@ -10,7 +10,7 @@ pub fn target() -> Target {
std: None,
},
pointer_width: 64,
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(),
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
arch: "loongarch64".into(),
options: TargetOptions {
cpu: "generic".into(),

View File

@ -11,7 +11,7 @@ pub fn target() -> Target {
std: None,
},
pointer_width: 64,
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(),
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
arch: "loongarch64".into(),
options: TargetOptions {
cpu: "generic".into(),

View File

@ -11,7 +11,7 @@ pub fn target() -> Target {
std: None,
},
pointer_width: 64,
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(),
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
arch: "loongarch64".into(),
options: TargetOptions {
cpu: "generic".into(),

View File

@ -18,6 +18,7 @@ pub fn target() -> Target {
let mut options = base::wasm::options();
options.os = "wasi".into();
options.env = "p1".into();
options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &["--target=wasm32-wasi"]);
options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained();

View File

@ -13,6 +13,7 @@ pub fn target() -> Target {
let mut options = base::wasm::options();
options.os = "wasi".into();
options.env = "p1".into();
options.add_pre_link_args(
LinkerFlavor::WasmLld(Cc::No),

View File

@ -1134,7 +1134,9 @@ pub fn rustc_cargo_env(
}
// Enable rustc's env var for `rust-lld` when requested.
if builder.config.lld_enabled {
if builder.config.lld_enabled
&& (builder.config.channel == "dev" || builder.config.channel == "nightly")
{
cargo.env("CFG_USE_SELF_CONTAINED_LINKER", "1");
}

View File

@ -150,3 +150,15 @@ or another engine that supports `wasi-threads` is installed and can be found in
5. Apply such [a change](https://github.com/g0djan/rust/compare/godjan/wasi-threads...g0djan:rust:godjan/wasi-run-ui-tests?expand=1) with an engine from the step 1.
6. Run `./x.py test --target wasm32-wasip1-threads tests/ui` and save the list of failed tests.
7. For both lists of failed tests run `cat list | sort > sorted_list` and compare it with `diff sorted_list1 sorted_list2`.
## Conditionally compiling code
It's recommended to conditionally compile code for this target with:
```text
#[cfg(all(target_os = "wasi", target_env = "p1", target_feature = "atomics"))]
```
Prior to Rust 1.80 the `target_env = "p1"` key was not set. Currently the
`target_feature = "atomics"` is Nightly-only. Note that the precise `#[cfg]`
necessary to detect this target may change as the target becomes more stable.

View File

@ -121,3 +121,14 @@ can be tested locally, for example, with:
```text
./x.py test --target wasm32-wasip1 tests/ui
```
## Conditionally compiling code
It's recommended to conditionally compile code for this target with:
```text
#[cfg(all(target_os = "wasi", target_env = "p1"))]
```
Note that the `target_env = "p1"` condition first appeared in Rust 1.80. Prior
to Rust 1.80 the `target_env` condition was not set.

View File

@ -53,3 +53,11 @@ This target is not tested in CI at this time. Locally it can be tested with a
```text
./x.py test --target wasm32-wasip2 tests/ui
```
## Conditionally compiling code
It's recommended to conditionally compile code for this target with:
```text
#[cfg(all(target_os = "wasi", target_env = "p2"))]
```

View File

@ -105,6 +105,12 @@ impl Rustc {
self
}
//Adjust the backtrace level, displaying more detailed information at higher levels.
pub fn set_backtrace_level<R: AsRef<OsStr>>(&mut self, level: R) -> &mut Self {
self.cmd.env("RUST_BACKTRACE", level);
self
}
/// Specify path to the output file. Equivalent to `-o`` in rustc.
pub fn output<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self.cmd.arg("-o");

View File

@ -214,7 +214,6 @@ run-make/sepcomp-cci-copies/Makefile
run-make/sepcomp-inlining/Makefile
run-make/sepcomp-separate/Makefile
run-make/share-generics-dylib/Makefile
run-make/short-ice/Makefile
run-make/silly-file-names/Makefile
run-make/simd-ffi/Makefile
run-make/split-debuginfo/Makefile

View File

@ -444,7 +444,9 @@ pub fn check(path: &Path, bad: &mut bool) {
suppressible_tidy_err!(err, skip_cr, "CR character");
}
if filename != "style.rs" {
if trimmed.contains("TODO") {
// Allow using TODO in diagnostic suggestions by marking the
// relevant line with `// ignore-tidy-todo`.
if trimmed.contains("TODO") && !trimmed.contains("ignore-tidy-todo") {
err(
"TODO is used for tasks that should be done before merging a PR; If you want to leave a message in the codebase use FIXME",
)

View File

@ -1,10 +0,0 @@
include ../tools.mk
# ignore-windows
export RUSTC := $(RUSTC_ORIGINAL)
export LD_LIBRARY_PATH := $(HOST_RPATH_DIR)
export TMPDIR := $(TMPDIR)
all:
bash check.sh

View File

@ -1,36 +0,0 @@
#!/bin/sh
export RUSTC_ICE=0
RUST_BACKTRACE=1 $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-1.log 2>&1
RUST_BACKTRACE=full $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-2.log 2>&1
short=$(cat $TMPDIR/rust-test-1.log | wc -l)
full=$(cat $TMPDIR/rust-test-2.log | wc -l)
rustc_query_count=$(cat $TMPDIR/rust-test-1.log | grep rustc_query_ | wc -l)
rustc_query_count_full=$(cat $TMPDIR/rust-test-2.log | grep rustc_query_ | wc -l)
begin_count=$(cat $TMPDIR/rust-test-2.log | grep __rust_begin_short_backtrace | wc -l)
end_count=$(cat $TMPDIR/rust-test-2.log | grep __rust_end_short_backtrace | wc -l)
cat $TMPDIR/rust-test-1.log
echo "====================="
cat $TMPDIR/rust-test-2.log
echo "====================="
echo "short backtrace: $short"
echo "full backtrace: $full"
echo "begin_count: $begin_count"
echo "end_count : $end_count"
echo "rustc_query_count: $rustc_query_count"
echo "rustc_query_count_full: $rustc_query_count_full"
## backtraces to vary a bit depending on platform and configuration options,
## here we make sure that the short backtrace of rustc_query is shorter than the full,
## and marks are in pairs.
if [ $short -lt $full ] &&
[ $begin_count -eq $end_count ] &&
[ $(($rustc_query_count + 5)) -lt $rustc_query_count_full ] &&
[ $rustc_query_count_full -gt 5 ]; then
exit 0
else
exit 1
fi

View File

@ -0,0 +1,42 @@
// Backtraces in internal compiler errors used to be unbearably long, spanning
// multiple hundreds of lines. A fix was pushed in #108938, and this test gathers
// varied metrics on level 1 and full-level backtraces to check that the output
// was shortened down to an appropriate length.
// See https://github.com/rust-lang/rust/issues/107910
//@ ignore-windows
// Reason: the assert_eq! on line 32 fails, as error output on Windows is different.
use run_make_support::rustc;
fn main() {
let rust_test_1 =
rustc().set_backtrace_level("1").input("src/lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
let rust_test_2 = rustc()
.set_backtrace_level("full")
.input("src/lib.rs")
.arg("-Ztreat-err-as-bug=1")
.run_fail();
let mut rust_test_log_1 = rust_test_1.stderr_utf8();
rust_test_log_1.push_str(&rust_test_1.stdout_utf8());
let rust_test_log_1 = rust_test_log_1.as_str();
let mut rust_test_log_2 = rust_test_2.stderr_utf8();
rust_test_log_2.push_str(&rust_test_2.stdout_utf8());
let rust_test_log_2 = rust_test_log_2.as_str();
let rustc_query_count_full = count_lines_with(rust_test_log_2, "rustc_query_");
assert!(rust_test_log_1.lines().count() < rust_test_log_2.lines().count());
assert_eq!(
count_lines_with(rust_test_log_2, "__rust_begin_short_backtrace"),
count_lines_with(rust_test_log_2, "__rust_end_short_backtrace")
);
assert!(count_lines_with(rust_test_log_1, "rustc_query_") + 5 < rustc_query_count_full);
assert!(rustc_query_count_full > 5);
}
fn count_lines_with(s: &str, search: &str) -> usize {
s.lines().filter(|l| l.contains(search)).count()
}

View File

@ -147,7 +147,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
LL | target_env = "_UNEXPECTED_VALUE",
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p2`, `psx`, `relibc`, `sgx`, and `uclibc`
= note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p1`, `p2`, `psx`, `relibc`, `sgx`, and `uclibc`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`

View File

@ -0,0 +1,52 @@
#![deny(dead_code)]
struct T1; //~ ERROR struct `T1` is never constructed
pub struct T2(i32); //~ ERROR struct `T2` is never constructed
struct T3;
trait Trait1 { //~ ERROR trait `Trait1` is never used
const UNUSED: i32;
fn unused(&self) {}
fn construct_self() -> Self;
}
pub trait Trait2 {
const USED: i32;
fn used(&self) {}
}
pub trait Trait3 {
const USED: i32;
fn construct_self() -> Self;
}
impl Trait1 for T1 {
const UNUSED: i32 = 0;
fn construct_self() -> Self {
Self
}
}
impl Trait1 for T2 {
const UNUSED: i32 = 0;
fn construct_self() -> Self {
T2(0)
}
}
impl Trait2 for T1 {
const USED: i32 = 0;
}
impl Trait2 for T2 {
const USED: i32 = 0;
}
impl Trait3 for T3 {
const USED: i32 = 0;
fn construct_self() -> Self {
Self
}
}
fn main() {}

View File

@ -0,0 +1,26 @@
error: struct `T1` is never constructed
--> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:3:8
|
LL | struct T1;
| ^^
|
note: the lint level is defined here
--> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:1:9
|
LL | #![deny(dead_code)]
| ^^^^^^^^^
error: struct `T2` is never constructed
--> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:4:12
|
LL | pub struct T2(i32);
| ^^
error: trait `Trait1` is never used
--> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:7:7
|
LL | trait Trait1 {
| ^^^^^^
error: aborting due to 3 previous errors

View File

@ -6,9 +6,11 @@ use std::env;
#[deny(unused_unsafe)]
fn main() {
// TODO: Audit that the environment access only happens in single-threaded code.
unsafe { env::set_var("FOO", "BAR") };
//~^ ERROR call to deprecated safe function
//~| WARN this is accepted in the current edition
// TODO: Audit that the environment access only happens in single-threaded code.
unsafe { env::remove_var("FOO") };
//~^ ERROR call to deprecated safe function
//~| WARN this is accepted in the current edition

View File

@ -13,8 +13,9 @@ LL | #![deny(deprecated_safe)]
| ^^^^^^^^^^^^^^^
help: you can wrap the call in an `unsafe` block if you can guarantee the code is only ever called from single-threaded code
|
LL | unsafe { env::set_var("FOO", "BAR") };
| ++++++++ +
LL + // TODO: Audit that the environment access only happens in single-threaded code.
LL ~ unsafe { env::set_var("FOO", "BAR") };
|
error: call to deprecated safe function `std::env::remove_var` is unsafe and requires unsafe block
--> $DIR/unsafe-env-suggestion.rs:12:5
@ -26,8 +27,9 @@ LL | env::remove_var("FOO");
= note: for more information, see issue #27970 <https://github.com/rust-lang/rust/issues/27970>
help: you can wrap the call in an `unsafe` block if you can guarantee the code is only ever called from single-threaded code
|
LL | unsafe { env::remove_var("FOO") };
| ++++++++ +
LL + // TODO: Audit that the environment access only happens in single-threaded code.
LL ~ unsafe { env::remove_var("FOO") };
|
error: aborting due to 2 previous errors