From ad7c2b06609c0da21ebdab6e45135cf07290f585 Mon Sep 17 00:00:00 2001 From: Oliver Killane Date: Sun, 5 May 2024 13:54:33 +0100 Subject: [PATCH 1/7] Updated error code explanation --- .../src/error_codes/E0582.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/compiler/rustc_error_codes/src/error_codes/E0582.md b/compiler/rustc_error_codes/src/error_codes/E0582.md index e50cc60ea3302..ea32e4f9f33f1 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0582.md +++ b/compiler/rustc_error_codes/src/error_codes/E0582.md @@ -27,6 +27,40 @@ fn bar(t: F, u: G) fn main() { } ``` +This error also includes the use of associated types with lifetime parameters. +```compile_fail,E0582 +trait Foo { + type Assoc<'a>; +} + +struct Bar +where + X: Foo, + F: for<'a> Fn(X::Assoc<'a>) -> &'a i32 +{ + x: X, + f: F +} +``` +This is as `Foo::Assoc<'a>` could be implemented by a type that does not use +the `'a` parameter, so there is no guarentee that `X::Assoc<'a>` actually uses +`'a`. + +To fix this we can pass a dummy parameter: +``` +# trait Foo { +# type Assoc<'a>; +# } +struct Bar +where + X: Foo, + F: for<'a> Fn(X::Assoc<'a>, /* dummy */ &'a ()) -> &'a i32 +{ + x: X, + f: F +} +``` + Note: The examples above used to be (erroneously) accepted by the compiler, but this was since corrected. See [issue #33685] for more details. From f3dcf65985dd956595a3f14dcb2a3052daceeb73 Mon Sep 17 00:00:00 2001 From: Oliver Killane Date: Sun, 5 May 2024 14:55:16 +0100 Subject: [PATCH 2/7] fix whitespace --- compiler/rustc_error_codes/src/error_codes/E0582.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0582.md b/compiler/rustc_error_codes/src/error_codes/E0582.md index ea32e4f9f33f1..31927cd5fe34f 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0582.md +++ b/compiler/rustc_error_codes/src/error_codes/E0582.md @@ -42,8 +42,8 @@ where f: F } ``` -This is as `Foo::Assoc<'a>` could be implemented by a type that does not use -the `'a` parameter, so there is no guarentee that `X::Assoc<'a>` actually uses +This is as `Foo::Assoc<'a>` could be implemented by a type that does not use +the `'a` parameter, so there is no guarentee that `X::Assoc<'a>` actually uses `'a`. To fix this we can pass a dummy parameter: From 4db00fe229f08b06feeee552ae53af9f49c25048 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Fri, 10 May 2024 16:38:19 +0200 Subject: [PATCH 3/7] Use an helper to move the files In case the source is not in the same filesystem. --- src/bootstrap/src/core/build_steps/dist.rs | 6 ++++-- src/bootstrap/src/core/download.rs | 6 +++--- src/bootstrap/src/utils/helpers.rs | 15 +++++++++++++++ src/bootstrap/src/utils/tarball.rs | 4 ++-- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 5bc9d7615e2bc..1f006e1453f4b 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -26,7 +26,9 @@ use crate::core::build_steps::tool::{self, Tool}; use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::core::config::TargetSelection; use crate::utils::channel::{self, Info}; -use crate::utils::helpers::{exe, is_dylib, output, t, target_supports_cranelift_backend, timeit}; +use crate::utils::helpers::{ + exe, is_dylib, move_file, output, t, target_supports_cranelift_backend, timeit, +}; use crate::utils::tarball::{GeneratedTarball, OverlayKind, Tarball}; use crate::{Compiler, DependencyType, Mode, LLVM_TOOLS}; @@ -2024,7 +2026,7 @@ impl Step for Extended { builder.run(&mut cmd); if !builder.config.dry_run() { - t!(fs::rename(exe.join(&filename), distdir(builder).join(&filename))); + t!(move_file(exe.join(&filename), distdir(builder).join(&filename))); } } } diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index a074d53aa36e6..60f48c5923e1c 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -12,7 +12,7 @@ use build_helper::ci::CiEnv; use build_helper::stage0_parser::VersionMetadata; use xz2::bufread::XzDecoder; -use crate::utils::helpers::{check_run, exe, program_out_of_date}; +use crate::utils::helpers::{check_run, exe, move_file, program_out_of_date}; use crate::{core::build_steps::llvm::detect_llvm_sha, utils::helpers::hex_encode}; use crate::{t, Config}; @@ -209,7 +209,7 @@ impl Config { None => panic!("no protocol in {url}"), } t!( - std::fs::rename(&tempfile, dest_path), + move_file(&tempfile, dest_path), format!("failed to rename {tempfile:?} to {dest_path:?}") ); } @@ -313,7 +313,7 @@ impl Config { if src_path.is_dir() && dst_path.exists() { continue; } - t!(fs::rename(src_path, dst_path)); + t!(move_file(src_path, dst_path)); } let dst_dir = dst.join(directory_prefix); if dst_dir.exists() { diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 0d2ff4f951b61..278359cb08e39 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -150,6 +150,21 @@ pub fn symlink_dir(config: &Config, original: &Path, link: &Path) -> io::Result< } } +/// Rename a file if from and to are in the same filesystem or +/// copy and remove the file otherwise +pub fn move_file, Q: AsRef>(from: P, to: Q) -> io::Result<()> { + match fs::rename(&from, &to) { + // FIXME: Once `ErrorKind::CrossesDevices` is stabilized use + // if e.kind() == io::ErrorKind::CrossesDevices { + #[cfg(unix)] + Err(e) if e.raw_os_error() == Some(libc::EXDEV) => { + std::fs::copy(&from, &to)?; + std::fs::remove_file(&from) + } + r => r, + } +} + pub fn forcing_clang_based_tests() -> bool { if let Some(var) = env::var_os("RUSTBUILD_FORCE_CLANG_BASED_TESTS") { match &var.to_string_lossy().to_lowercase()[..] { diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index 2a950e669b923..57cdf7473a191 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -13,7 +13,7 @@ use std::{ use crate::core::builder::Builder; use crate::core::{build_steps::dist::distdir, builder::Kind}; use crate::utils::channel; -use crate::utils::helpers::t; +use crate::utils::helpers::{move_file, t}; #[derive(Copy, Clone)] pub(crate) enum OverlayKind { @@ -284,7 +284,7 @@ impl<'a> Tarball<'a> { // name, not "image". We rename the image directory just before passing // into rust-installer. let dest = self.temp_dir.join(self.package_name()); - t!(std::fs::rename(&self.image_dir, &dest)); + t!(move_file(&self.image_dir, &dest)); self.run(|this, cmd| { let distdir = distdir(this.builder); From fe8f66e4bcbe36e7e4b21943661ff23b5369c64b Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Mon, 13 May 2024 13:32:31 -0400 Subject: [PATCH 4/7] `rustc_hir_typeck`: Account for `skipped_ref_pats` in `expr_use_visitor` Fixes #125058 --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 12 +++++++++- .../pattern/skipped-ref-pats-issue-125058.rs | 18 ++++++++++++++ .../skipped-ref-pats-issue-125058.stderr | 24 +++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 tests/ui/pattern/skipped-ref-pats-issue-125058.rs create mode 100644 tests/ui/pattern/skipped-ref-pats-issue-125058.stderr diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 1864c7e6ef82d..89f62577506fd 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -18,12 +18,12 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, Res}; use rustc_hir::def_id::LocalDefId; use rustc_hir::{HirId, PatKind}; -use rustc_middle::{bug, span_bug}; use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{ self, adjustment, AdtKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt as _, }; +use rustc_middle::{bug, span_bug}; use rustc_span::{ErrorGuaranteed, Span}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use rustc_trait_selection::infer::InferCtxtExt; @@ -1181,6 +1181,10 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx debug!("pat_ty(pat={:?}) found adjusted ty `{:?}`", pat, first_ty); return Ok(*first_ty); } + } else if let PatKind::Ref(subpat, _) = pat.kind + && self.cx.typeck_results().skipped_ref_pats().contains(pat.hir_id) + { + return self.pat_ty_adjusted(subpat); } self.pat_ty_unadjusted(pat) @@ -1712,6 +1716,12 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx self.cat_pattern(place_with_id, subpat, op)?; } + PatKind::Ref(subpat, _) + if self.cx.typeck_results().skipped_ref_pats().contains(pat.hir_id) => + { + self.cat_pattern(place_with_id, subpat, op)?; + } + PatKind::Box(subpat) | PatKind::Ref(subpat, _) => { // box p1, &p1, &mut p1. we can ignore the mutability of // PatKind::Ref since that information is already contained diff --git a/tests/ui/pattern/skipped-ref-pats-issue-125058.rs b/tests/ui/pattern/skipped-ref-pats-issue-125058.rs new file mode 100644 index 0000000000000..b733e5fda0a26 --- /dev/null +++ b/tests/ui/pattern/skipped-ref-pats-issue-125058.rs @@ -0,0 +1,18 @@ +//@ run-pass +//@ edition: 2024 +//@ compile-flags: -Zunstable-options + +#![allow(incomplete_features)] +#![feature(ref_pat_eat_one_layer_2024)] + +struct Foo; +//~^ WARN struct `Foo` is never constructed + +fn main() { + || { + //~^ WARN unused closure that must be used + if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + let _: u32 = x; + } + }; +} diff --git a/tests/ui/pattern/skipped-ref-pats-issue-125058.stderr b/tests/ui/pattern/skipped-ref-pats-issue-125058.stderr new file mode 100644 index 0000000000000..cee1cc673c7e6 --- /dev/null +++ b/tests/ui/pattern/skipped-ref-pats-issue-125058.stderr @@ -0,0 +1,24 @@ +warning: struct `Foo` is never constructed + --> $DIR/skipped-ref-pats-issue-125058.rs:8:8 + | +LL | struct Foo; + | ^^^ + | + = note: `#[warn(dead_code)]` on by default + +warning: unused closure that must be used + --> $DIR/skipped-ref-pats-issue-125058.rs:12:5 + | +LL | / || { +LL | | +LL | | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { +LL | | let _: u32 = x; +LL | | } +LL | | }; + | |_____^ + | + = note: closures are lazy and do nothing unless called + = note: `#[warn(unused_must_use)]` on by default + +warning: 2 warnings emitted + From 1f5837ae2506d5439b31195b7fcf784b9ee90d2b Mon Sep 17 00:00:00 2001 From: Oneirical Date: Sat, 11 May 2024 17:20:31 -0400 Subject: [PATCH 5/7] rewrite c-link-to-rust-staticlib --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../c-link-to-rust-staticlib/Makefile | 16 --------------- .../c-link-to-rust-staticlib/rmake.rs | 20 +++++++++++++++++++ 3 files changed, 20 insertions(+), 17 deletions(-) delete mode 100644 tests/run-make/c-link-to-rust-staticlib/Makefile create mode 100644 tests/run-make/c-link-to-rust-staticlib/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 5f68f779c4eb0..37acd768593eb 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -8,7 +8,6 @@ run-make/branch-protection-check-IBT/Makefile run-make/c-dynamic-dylib/Makefile run-make/c-dynamic-rlib/Makefile run-make/c-link-to-rust-dylib/Makefile -run-make/c-link-to-rust-staticlib/Makefile run-make/c-static-dylib/Makefile run-make/c-static-rlib/Makefile run-make/c-unwind-abi-catch-lib-panic/Makefile diff --git a/tests/run-make/c-link-to-rust-staticlib/Makefile b/tests/run-make/c-link-to-rust-staticlib/Makefile deleted file mode 100644 index d36cc421c468a..0000000000000 --- a/tests/run-make/c-link-to-rust-staticlib/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# This test checks that C linking with Rust does not encounter any errors, with static libraries. -# See https://github.com/rust-lang/rust/issues/10434 - -# ignore-cross-compile -include ../tools.mk - -# ignore-freebsd -# FIXME - -all: - $(RUSTC) foo.rs - $(CC) bar.c $(call STATICLIB,foo) $(call OUT_EXE,bar) \ - $(EXTRACFLAGS) $(EXTRACXXFLAGS) - $(call RUN,bar) - rm $(call STATICLIB,foo) - $(call RUN,bar) diff --git a/tests/run-make/c-link-to-rust-staticlib/rmake.rs b/tests/run-make/c-link-to-rust-staticlib/rmake.rs new file mode 100644 index 0000000000000..d73ca413777d2 --- /dev/null +++ b/tests/run-make/c-link-to-rust-staticlib/rmake.rs @@ -0,0 +1,20 @@ +// This test checks that C linking with Rust does not encounter any errors, with a static library. +// See https://github.com/rust-lang/rust/issues/10434 + +//@ ignore-cross-compile + +use run_make_support::{cc, extra_c_flags, extra_cxx_flags, run, rustc, static_lib}; +use std::fs; + +fn main() { + rustc().input("foo.rs").run(); + cc().input("bar.c") + .input(static_lib("foo")) + .out_exe("bar") + .args(&extra_c_flags()) + .args(&extra_cxx_flags()) + .run(); + run("bar"); + fs::remove_file(static_lib("foo")); + run("bar"); +} From b1e5e5161a2ef27852aab40cf3472187bdda5fee Mon Sep 17 00:00:00 2001 From: Julien <96022417+Oneirical@users.noreply.github.com> Date: Tue, 14 May 2024 16:43:39 -0400 Subject: [PATCH 6/7] remove cxx_flags --- tests/run-make/c-link-to-rust-staticlib/rmake.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/run-make/c-link-to-rust-staticlib/rmake.rs b/tests/run-make/c-link-to-rust-staticlib/rmake.rs index d73ca413777d2..762d7953a9a0f 100644 --- a/tests/run-make/c-link-to-rust-staticlib/rmake.rs +++ b/tests/run-make/c-link-to-rust-staticlib/rmake.rs @@ -3,7 +3,7 @@ //@ ignore-cross-compile -use run_make_support::{cc, extra_c_flags, extra_cxx_flags, run, rustc, static_lib}; +use run_make_support::{cc, extra_c_flags, run, rustc, static_lib}; use std::fs; fn main() { @@ -12,7 +12,6 @@ fn main() { .input(static_lib("foo")) .out_exe("bar") .args(&extra_c_flags()) - .args(&extra_cxx_flags()) .run(); run("bar"); fs::remove_file(static_lib("foo")); From 1f61cc3078ce6bcca8095778310f73fc45f7193e Mon Sep 17 00:00:00 2001 From: Oneirical Date: Mon, 13 May 2024 23:30:50 -0400 Subject: [PATCH 7/7] port no-cdylib-as-rdylib test --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/no-cdylib-as-rdylib/Makefile | 16 ---------------- tests/run-make/no-cdylib-as-rdylib/rmake.rs | 16 ++++++++++++++++ 3 files changed, 16 insertions(+), 17 deletions(-) delete mode 100644 tests/run-make/no-cdylib-as-rdylib/Makefile create mode 100644 tests/run-make/no-cdylib-as-rdylib/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 d742368292035..fc2ba589d2442 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -185,7 +185,6 @@ run-make/native-link-modifier-whole-archive/Makefile run-make/no-alloc-shim/Makefile run-make/no-builtins-attribute/Makefile run-make/no-builtins-lto/Makefile -run-make/no-cdylib-as-rdylib/Makefile run-make/no-duplicate-libs/Makefile run-make/no-intermediate-extras/Makefile run-make/obey-crate-type-flag/Makefile diff --git a/tests/run-make/no-cdylib-as-rdylib/Makefile b/tests/run-make/no-cdylib-as-rdylib/Makefile deleted file mode 100644 index 4d2be0aea913d..0000000000000 --- a/tests/run-make/no-cdylib-as-rdylib/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# Test that rustc will not attempt to link against a cdylib as if -# it is a rust dylib when an rlib for the same crate is available. -# Previously rustc didn't actually check if any further formats of -# a crate which has been loaded are of the same version and if -# they are actually valid. This caused a cdylib to be interpreted -# as rust dylib as soon as the corresponding rlib was loaded. As -# cdylibs don't export any rust symbols, linking would fail if -# rustc decides to link against the cdylib rather than the rlib. - -all: - $(RUSTC) bar.rs --crate-type=rlib --crate-type=cdylib - $(RUSTC) foo.rs -C prefer-dynamic - $(call RUN,foo) diff --git a/tests/run-make/no-cdylib-as-rdylib/rmake.rs b/tests/run-make/no-cdylib-as-rdylib/rmake.rs new file mode 100644 index 0000000000000..42e89df6c2b61 --- /dev/null +++ b/tests/run-make/no-cdylib-as-rdylib/rmake.rs @@ -0,0 +1,16 @@ +// This test produces an rlib and a cdylib from bar.rs. +// Then, foo.rs attempts to link to the bar library. +// If the test passes, that means rustc favored the rlib and ignored the cdylib. +// If the test fails, that is because the cdylib was picked, which does not export +// any Rust symbols. +// See https://github.com/rust-lang/rust/pull/113695 + +//@ ignore-cross-compile + +use run_make_support::{run, rustc}; + +fn main() { + rustc().input("bar.rs").crate_type("rlib").crate_type("cdylib").run(); + rustc().input("foo.rs").arg("-Cprefer-dynamic").run(); + run("foo"); +}