From 3df9afcae781c2d9db5a2cb9acde9be5ae753285 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 13 Oct 2022 07:33:34 +0000 Subject: [PATCH 01/12] rustdoc: don't ICE on `TyKind::Typeof` --- src/librustdoc/clean/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8d556a962d9f5..7f82dfbd3d6ff 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1543,8 +1543,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T } TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))), // Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s. - TyKind::Infer | TyKind::Err => Infer, - TyKind::Typeof(..) => panic!("unimplemented type {:?}", ty.kind), + TyKind::Infer | TyKind::Err | TyKind::Typeof(..) => Infer, } } From 097b6d3bafb1d61bfe8fd3f5e9d9acfd9ee2c702 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Wed, 12 Oct 2022 22:52:31 -0400 Subject: [PATCH 02/12] Add suggestion to the "missing native library" error If we fail to locate a native library that we are linking with, it could be the case the user entered a complete file name like `foo.lib` or `libfoo.a` when we expect them to simply provide `foo`. In this situation, we now detect that case and suggest the user only provide the library name itself. --- .../locales/en-US/metadata.ftl | 2 ++ compiler/rustc_metadata/src/errors.rs | 36 ++++++++++++++++++- compiler/rustc_metadata/src/native_libs.rs | 2 +- .../suggest-libname-only-1.rs | 9 +++++ .../suggest-libname-only-1.stderr | 6 ++++ .../suggest-libname-only-2.rs | 9 +++++ .../suggest-libname-only-2.stderr | 6 ++++ 7 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/native-library-link-flags/suggest-libname-only-1.rs create mode 100644 src/test/ui/native-library-link-flags/suggest-libname-only-1.stderr create mode 100644 src/test/ui/native-library-link-flags/suggest-libname-only-2.rs create mode 100644 src/test/ui/native-library-link-flags/suggest-libname-only-2.stderr diff --git a/compiler/rustc_error_messages/locales/en-US/metadata.ftl b/compiler/rustc_error_messages/locales/en-US/metadata.ftl index d27100c56aff5..08e553d9f1589 100644 --- a/compiler/rustc_error_messages/locales/en-US/metadata.ftl +++ b/compiler/rustc_error_messages/locales/en-US/metadata.ftl @@ -165,6 +165,8 @@ metadata_failed_write_error = metadata_missing_native_library = could not find native static library `{$libname}`, perhaps an -L flag is missing? +metadata_only_provide_library_name = only provide the library name `{$suggested_name}`, not the full filename + metadata_failed_create_tempdir = couldn't create a temp dir: {$err} diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 1cd550644bf4d..dbfa22aaff074 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -372,7 +372,41 @@ pub struct FailedWriteError { #[derive(Diagnostic)] #[diag(metadata::missing_native_library)] pub struct MissingNativeLibrary<'a> { - pub libname: &'a str, + libname: &'a str, + #[subdiagnostic] + suggest_name: Option>, +} + +impl<'a> MissingNativeLibrary<'a> { + pub fn new(libname: &'a str, verbatim: bool) -> Self { + // if it looks like the user has provided a complete filename rather just the bare lib name, + // then provide a note that they might want to try trimming the name + let suggested_name = if !verbatim { + if let Some(libname) = libname.strip_prefix("lib") && let Some(libname) = libname.strip_suffix(".a") { + // this is a unix style filename so trim prefix & suffix + Some(libname) + } else if let Some(libname) = libname.strip_suffix(".lib") { + // this is a Windows style filename so just trim the suffix + Some(libname) + } else { + None + } + } else { + None + }; + + Self { + libname, + suggest_name: suggested_name + .map(|suggested_name| SuggestLibraryName { suggested_name }), + } + } +} + +#[derive(Subdiagnostic)] +#[help(metadata::only_provide_library_name)] +pub struct SuggestLibraryName<'a> { + suggested_name: &'a str, } #[derive(Diagnostic)] diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 9abb5c74895d0..676c67bad827f 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -52,7 +52,7 @@ pub fn find_native_static_library( } } - sess.emit_fatal(MissingNativeLibrary { libname: name }); + sess.emit_fatal(MissingNativeLibrary::new(name, verbatim.unwrap_or(false))); } fn find_bundled_library( diff --git a/src/test/ui/native-library-link-flags/suggest-libname-only-1.rs b/src/test/ui/native-library-link-flags/suggest-libname-only-1.rs new file mode 100644 index 0000000000000..abf988a7c1ed3 --- /dev/null +++ b/src/test/ui/native-library-link-flags/suggest-libname-only-1.rs @@ -0,0 +1,9 @@ +// build-fail +// compile-flags: --crate-type rlib +// error-pattern: could not find native static library `libfoo.a` +// error-pattern: only provide the library name `foo`, not the full filename + +#[link(name = "libfoo.a", kind = "static")] +extern { } + +pub fn main() { } diff --git a/src/test/ui/native-library-link-flags/suggest-libname-only-1.stderr b/src/test/ui/native-library-link-flags/suggest-libname-only-1.stderr new file mode 100644 index 0000000000000..64d0a9077ed15 --- /dev/null +++ b/src/test/ui/native-library-link-flags/suggest-libname-only-1.stderr @@ -0,0 +1,6 @@ +error: could not find native static library `libfoo.a`, perhaps an -L flag is missing? + | + = help: only provide the library name `foo`, not the full filename + +error: aborting due to previous error + diff --git a/src/test/ui/native-library-link-flags/suggest-libname-only-2.rs b/src/test/ui/native-library-link-flags/suggest-libname-only-2.rs new file mode 100644 index 0000000000000..dfa70e56db73c --- /dev/null +++ b/src/test/ui/native-library-link-flags/suggest-libname-only-2.rs @@ -0,0 +1,9 @@ +// build-fail +// compile-flags: --crate-type rlib +// error-pattern: could not find native static library `bar.lib` +// error-pattern: only provide the library name `bar`, not the full filename + +#[link(name = "bar.lib", kind = "static")] +extern { } + +pub fn main() { } diff --git a/src/test/ui/native-library-link-flags/suggest-libname-only-2.stderr b/src/test/ui/native-library-link-flags/suggest-libname-only-2.stderr new file mode 100644 index 0000000000000..e166af9ed8f03 --- /dev/null +++ b/src/test/ui/native-library-link-flags/suggest-libname-only-2.stderr @@ -0,0 +1,6 @@ +error: could not find native static library `bar.lib`, perhaps an -L flag is missing? + | + = help: only provide the library name `bar`, not the full filename + +error: aborting due to previous error + From c47337e1150d1a214c04f9e5b532c80e8d7a89d0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 13 Oct 2022 16:50:11 +0200 Subject: [PATCH 03/12] Update browser-ui-test version to 0.12.3 --- .../docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index e96a87111cbbd..d61567cd134a3 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.12.2 \ No newline at end of file +0.12.3 \ No newline at end of file From 16cfd6cc8446215ec31dfd2e79a61e68fc8f276c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 13 Oct 2022 16:51:04 +0200 Subject: [PATCH 04/12] Improve code for unsafe-fn rustdoc GUI test --- src/test/rustdoc-gui/unsafe-fn.goml | 53 ++++++++++++----------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/src/test/rustdoc-gui/unsafe-fn.goml b/src/test/rustdoc-gui/unsafe-fn.goml index 94f128db72e90..5e43b85fce084 100644 --- a/src/test/rustdoc-gui/unsafe-fn.goml +++ b/src/test/rustdoc-gui/unsafe-fn.goml @@ -1,37 +1,28 @@ +// Check position and color of the `` for unsafe elements. goto: "file://" + |DOC_PATH| + "/test_docs/index.html" - -compare-elements-property: ( - "//a[@title='test_docs::safe_fn fn']/..", - "//a[@title='test_docs::unsafe_fn fn']/..", - ["clientHeight"] -) - // If the text isn't displayed, the browser doesn't compute color style correctly... show-text: true -// Set the theme to dark. -local-storage: {"rustdoc-theme": "dark", "rustdoc-preferred-dark-theme": "dark", "rustdoc-use-system-theme": "false"} -// We reload the page so the local storage settings are being used. -reload: - -assert-css: (".item-left sup", { - "color": "rgb(221, 221, 221)" -}) - -// Set the theme to ayu. -local-storage: {"rustdoc-theme": "ayu", "rustdoc-preferred-dark-theme": "ayu", "rustdoc-use-system-theme": "false"} -// We reload the page so the local storage settings are being used. -reload: - -assert-css: (".item-left sup", { - "color": "rgb(197, 197, 197)" -}) +compare-elements-property: ( + "//a[@title='test_docs::safe_fn fn']/..", + "//a[@title='test_docs::unsafe_fn fn']/..", + ["clientHeight"] +) -// Set the theme to light. -local-storage: {"rustdoc-theme": "light", "rustdoc-preferred-dark-theme": "light", "rustdoc-use-system-theme": "false"} -// We reload the page so the local storage settings are being used. -reload: +define-function: ( + "sup-check", + // `theme` is the theme being tested. + // `color` is the expected color of the `` element. + (theme, color), + [ + // Set the theme. + ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), + // We reload the page so the local storage settings are being used. + ("reload"), + ("assert-css", (".item-left sup", {"color": |color|})), + ], +) -assert-css: (".item-left sup", { - "color": "rgb(0, 0, 0)" -}) +call-function: ("sup-check", ("dark", "rgb(221, 221, 221)")) +call-function: ("sup-check", ("ayu", "rgb(197, 197, 197)")) +call-function: ("sup-check", ("light", "rgb(0, 0, 0)")) From 577d2cfbcc9b7c8981e7faaf62981d1b5b35b8a8 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 13 Oct 2022 14:57:50 +0000 Subject: [PATCH 05/12] Add test for issue 102986 --- src/test/rustdoc-ui/issue-102986.rs | 4 ++++ src/test/rustdoc-ui/issue-102986.stderr | 14 ++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 src/test/rustdoc-ui/issue-102986.rs create mode 100644 src/test/rustdoc-ui/issue-102986.stderr diff --git a/src/test/rustdoc-ui/issue-102986.rs b/src/test/rustdoc-ui/issue-102986.rs new file mode 100644 index 0000000000000..001784ac28561 --- /dev/null +++ b/src/test/rustdoc-ui/issue-102986.rs @@ -0,0 +1,4 @@ +struct Struct { + y: (typeof("hey"),), + //~^ `typeof` is a reserved keyword but unimplemented +} diff --git a/src/test/rustdoc-ui/issue-102986.stderr b/src/test/rustdoc-ui/issue-102986.stderr new file mode 100644 index 0000000000000..3a573726c9727 --- /dev/null +++ b/src/test/rustdoc-ui/issue-102986.stderr @@ -0,0 +1,14 @@ +error[E0516]: `typeof` is a reserved keyword but unimplemented + --> $DIR/issue-102986.rs:2:9 + | +LL | y: (typeof("hey"),), + | ^^^^^^^^^^^^^ reserved keyword + | +help: consider replacing `typeof(...)` with an actual type + | +LL | y: (&'static str,), + | ~~~~~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0516`. From 6d609c5d6ed5339e4e235e0556a3656ab2697f4f Mon Sep 17 00:00:00 2001 From: nils <48135649+Nilstrieb@users.noreply.github.com> Date: Thu, 13 Oct 2022 17:38:30 +0200 Subject: [PATCH 06/12] Add new bootstrap entrypoints to triagebot --- triagebot.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 181fb1de93055..69bd49394099d 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -179,6 +179,8 @@ exclude_labels = [ [autolabel."A-bootstrap"] trigger_files = [ "x.py", + "x", + "x.ps1", "src/bootstrap", "src/tools/rust-installer", ] From de0396c7180f8e36165c3fefb9325b0ec1bfb5a2 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Thu, 13 Oct 2022 16:44:31 +0100 Subject: [PATCH 07/12] Ensure enum cast moves --- compiler/rustc_mir_build/src/build/expr/as_rvalue.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 35a00da8d38b2..3dafdcb788710 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -197,13 +197,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // create all the steps directly in MIR with operations all backends need to support anyway. let (source, ty) = if let ty::Adt(adt_def, ..) = source.ty.kind() && adt_def.is_enum() { let discr_ty = adt_def.repr().discr_type().to_ty(this.tcx); - let place = unpack!(block = this.as_place(block, source)); + let temp = unpack!(block = this.as_temp(block, scope, source, Mutability::Not)); let discr = this.temp(discr_ty, source.span); this.cfg.push_assign( block, source_info, discr, - Rvalue::Discriminant(place), + Rvalue::Discriminant(temp.into()), ); (Operand::Move(discr), discr_ty) From d2d3d9433228adb35cfec0de8f3747879e38751f Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Thu, 13 Oct 2022 13:49:38 +0300 Subject: [PATCH 08/12] replace ReErased with fresh region vars in opaque types --- .../rustc_hir_analysis/src/check/check.rs | 20 ++++-- .../closure_parent_substs.rs | 65 +++++++++++++++++++ .../closure_wf_outlives.rs | 65 +++++++++++++++++++ .../closure_wf_outlives.stderr | 64 ++++++++++++++++++ 4 files changed, 209 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/type-alias-impl-trait/closure_parent_substs.rs create mode 100644 src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs create mode 100644 src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 7cee9779c5f39..c3583eeb430be 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -732,8 +732,6 @@ fn check_opaque_meets_bounds<'tcx>( span: Span, origin: &hir::OpaqueTyOrigin, ) { - let hidden_type = tcx.bound_type_of(def_id.to_def_id()).subst(tcx, substs); - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); let defining_use_anchor = match *origin { hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did, @@ -748,14 +746,26 @@ fn check_opaque_meets_bounds<'tcx>( let ocx = ObligationCtxt::new(&infcx); let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs); + // `ReErased` regions appear in the "parent_substs" of closures/generators. + // We're ignoring them here and replacing them with fresh region variables. + // See tests in ui/type-alias-impl-trait/closure_{parent_substs,wf_outlives}.rs. + // + // FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it + // here rather than using ReErased. + let hidden_ty = tcx.bound_type_of(def_id.to_def_id()).subst(tcx, substs); + let hidden_ty = tcx.fold_regions(hidden_ty, |re, _dbi| match re.kind() { + ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)), + _ => re, + }); + let misc_cause = traits::ObligationCause::misc(span, hir_id); - match infcx.at(&misc_cause, param_env).eq(opaque_ty, hidden_type) { + match infcx.at(&misc_cause, param_env).eq(opaque_ty, hidden_ty) { Ok(infer_ok) => ocx.register_infer_ok_obligations(infer_ok), Err(ty_err) => { tcx.sess.delay_span_bug( span, - &format!("could not unify `{hidden_type}` with revealed type:\n{ty_err}"), + &format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"), ); } } @@ -764,7 +774,7 @@ fn check_opaque_meets_bounds<'tcx>( // Defining use functions may have more bounds than the opaque type, which is ok, as long as the // hidden type is well formed even without those bounds. let predicate = - ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_type.into())).to_predicate(tcx); + ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_ty.into())).to_predicate(tcx); ocx.register_obligation(Obligation::new(misc_cause, param_env, predicate)); // Check that all obligations are satisfied by the implementation's diff --git a/src/test/ui/type-alias-impl-trait/closure_parent_substs.rs b/src/test/ui/type-alias-impl-trait/closure_parent_substs.rs new file mode 100644 index 0000000000000..475f4724ff28f --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/closure_parent_substs.rs @@ -0,0 +1,65 @@ +// When WF checking the hidden type in the ParamEnv of the opaque type, +// one complication arises when the hidden type is a closure/generator: +// the "parent_substs" of the type may reference lifetime parameters +// not present in the opaque type. +// These region parameters are not really useful in this check. +// So here we ignore them and replace them with fresh region variables. + +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +// Basic test +mod test1 { + // Hidden type = Closure['_#0r] + type Opaque = impl Sized; + + fn define<'a: 'a>() -> Opaque { + || {} + } +} + +// the region vars cannot both be equal to `'static` or `'empty` +mod test2 { + trait Trait {} + + // Hidden type = Closure['a, '_#0r, '_#1r] + // Constraints = [('_#0r: 'a), ('a: '_#1r)] + type Opaque<'a> + where + &'a (): Trait, + = impl Sized + 'a; + + fn define<'a, 'x, 'y>() -> Opaque<'a> + where + &'a (): Trait, + 'x: 'a, + 'a: 'y, + { + || {} + } +} + +// the region var cannot be equal to `'a` or `'b` +mod test3 { + trait Trait {} + + // Hidden type = Closure['a, 'b, '_#0r] + // Constraints = [('_#0r: 'a), ('_#0r: 'b)] + type Opaque<'a, 'b> + where + (&'a (), &'b ()): Trait, + = impl Sized + 'a + 'b; + + fn define<'a, 'b, 'x>() -> Opaque<'a, 'b> + where + (&'a (), &'b ()): Trait, + 'x: 'a, + 'x: 'b, + { + || {} + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs new file mode 100644 index 0000000000000..53974dbb36bdf --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs @@ -0,0 +1,65 @@ +// If the hidden type is a closure, we require the "outlives" bounds that appear on the +// defining site to also appear on the opaque type. +// +// It's not clear if this is the desired behavior but at least +// it's consistent and has no back-compat risk. + +// check-fail + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +// requires `'a: 'b` bound +mod test1 { + type Opaque<'a, 'b> = impl Sized + 'a + 'b; + //~^ ERROR lifetime bound not satisfied + + fn define<'a, 'b>() -> Opaque<'a, 'b> + where + 'a: 'b, + { + || {} + } +} + +// Same as the above but through indirection `'x` +mod test2 { + type Opaque<'a, 'b> = impl Sized + 'a + 'b; + //~^ ERROR cannot infer an appropriate lifetime + + fn define<'a, 'b, 'x>() -> Opaque<'a, 'b> + where + 'a: 'x, + 'x: 'b, + { + || {} + } +} + +// fixed version of the above +mod test2_fixed { + type Opaque<'a: 'b, 'b> = impl Sized + 'a + 'b; + + fn define<'a, 'b, 'x>() -> Opaque<'a, 'b> + where + 'a: 'x, + 'x: 'b, + { + || {} + } +} + +// requires `T: 'static` +mod test3 { + type Opaque = impl Sized; + //~^ ERROR the parameter type `T` may not live long enough + + fn define() -> Opaque + where + T: 'static, + { + || {} + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr new file mode 100644 index 0000000000000..ae6462bb62ce5 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr @@ -0,0 +1,64 @@ +error[E0478]: lifetime bound not satisfied + --> $DIR/closure_wf_outlives.rs:14:27 + | +LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; + | ^^^^^^^^^^^^^^^^^^^^ + | +note: lifetime parameter instantiated with the lifetime `'a` as defined here + --> $DIR/closure_wf_outlives.rs:14:17 + | +LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; + | ^^ +note: but lifetime parameter must outlive the lifetime `'b` as defined here + --> $DIR/closure_wf_outlives.rs:14:21 + | +LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; + | ^^ + +error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements + --> $DIR/closure_wf_outlives.rs:27:27 + | +LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; + | ^^^^^^^^^^^^^^^^^^^^ + | +note: first, the lifetime cannot outlive the lifetime `'a` as defined here... + --> $DIR/closure_wf_outlives.rs:27:17 + | +LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; + | ^^ +note: ...so that the declared lifetime parameter bounds are satisfied + --> $DIR/closure_wf_outlives.rs:27:27 + | +LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; + | ^^^^^^^^^^^^^^^^^^^^ +note: but, the lifetime must be valid for the lifetime `'b` as defined here... + --> $DIR/closure_wf_outlives.rs:27:21 + | +LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; + | ^^ +note: ...so that the declared lifetime parameter bounds are satisfied + --> $DIR/closure_wf_outlives.rs:27:27 + | +LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/closure_wf_outlives.rs:54:22 + | +LL | type Opaque = impl Sized; + | ^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds... + | +note: ...that is required by this bound + --> $DIR/closure_wf_outlives.rs:59:12 + | +LL | T: 'static, + | ^^^^^^^ +help: consider adding an explicit lifetime bound... + | +LL | type Opaque = impl Sized; + | +++++++++ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0310, E0478, E0495. +For more information about an error, try `rustc --explain E0310`. From f1452fc1c99bc6d126a096694b0f70d9fe4734b6 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Thu, 13 Oct 2022 17:24:19 +0100 Subject: [PATCH 09/12] Add test for issue 102389 --- src/test/ui/mir/issue-102389.rs | 8 ++++++++ src/test/ui/mir/issue-102389.stderr | 9 +++++++++ 2 files changed, 17 insertions(+) create mode 100644 src/test/ui/mir/issue-102389.rs create mode 100644 src/test/ui/mir/issue-102389.stderr diff --git a/src/test/ui/mir/issue-102389.rs b/src/test/ui/mir/issue-102389.rs new file mode 100644 index 0000000000000..8b27d5e55743d --- /dev/null +++ b/src/test/ui/mir/issue-102389.rs @@ -0,0 +1,8 @@ +enum Enum { A, B, C } + +fn func(inbounds: &Enum, array: &[i16; 3]) -> i16 { + array[*inbounds as usize] + //~^ ERROR [E0507] +} + +fn main() {} diff --git a/src/test/ui/mir/issue-102389.stderr b/src/test/ui/mir/issue-102389.stderr new file mode 100644 index 0000000000000..925dc258a4c3c --- /dev/null +++ b/src/test/ui/mir/issue-102389.stderr @@ -0,0 +1,9 @@ +error[E0507]: cannot move out of `*inbounds` which is behind a shared reference + --> $DIR/issue-102389.rs:4:11 + | +LL | array[*inbounds as usize] + | ^^^^^^^^^ move occurs because `*inbounds` has type `Enum`, which does not implement the `Copy` trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`. From 247da7b18de01886fb73a49f8b9ca59cfec16e64 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Thu, 13 Oct 2022 17:24:27 +0100 Subject: [PATCH 10/12] Bless tests --- src/test/mir-opt/enum_cast.bar.mir_map.0.mir | 10 +++-- src/test/mir-opt/enum_cast.boo.mir_map.0.mir | 10 +++-- .../mir-opt/enum_cast.droppy.mir_map.0.mir | 40 ++++++++++++------- src/test/mir-opt/enum_cast.foo.mir_map.0.mir | 10 +++-- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/src/test/mir-opt/enum_cast.bar.mir_map.0.mir b/src/test/mir-opt/enum_cast.bar.mir_map.0.mir index 8b12525b576ff..e58085f701ac2 100644 --- a/src/test/mir-opt/enum_cast.bar.mir_map.0.mir +++ b/src/test/mir-opt/enum_cast.bar.mir_map.0.mir @@ -3,11 +3,15 @@ fn bar(_1: Bar) -> usize { debug bar => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11 let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26 - let mut _2: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let _2: Bar; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let mut _3: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 bb0: { - _2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 - _0 = move _2 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17 return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/enum_cast.boo.mir_map.0.mir b/src/test/mir-opt/enum_cast.boo.mir_map.0.mir index a77f4d06c239b..525c6234ed31d 100644 --- a/src/test/mir-opt/enum_cast.boo.mir_map.0.mir +++ b/src/test/mir-opt/enum_cast.boo.mir_map.0.mir @@ -3,11 +3,15 @@ fn boo(_1: Boo) -> usize { debug boo => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11 let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26 - let mut _2: u8; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let _2: Boo; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let mut _3: u8; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 bb0: { - _2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 - _0 = move _2 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17 return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir b/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir index ae3e71df8c6df..bb5faa48047a9 100644 --- a/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir +++ b/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir @@ -4,8 +4,9 @@ fn droppy() -> () { let mut _0: (); // return place in scope 0 at $DIR/enum_cast.rs:+0:13: +0:13 let _1: (); // in scope 0 at $DIR/enum_cast.rs:+1:5: +6:6 let _2: Droppy; // in scope 0 at $DIR/enum_cast.rs:+2:13: +2:14 - let mut _4: isize; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18 - let _5: Droppy; // in scope 0 at $DIR/enum_cast.rs:+7:9: +7:10 + let _4: Droppy; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18 + let mut _5: isize; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18 + let _6: Droppy; // in scope 0 at $DIR/enum_cast.rs:+7:9: +7:10 scope 1 { debug x => _2; // in scope 1 at $DIR/enum_cast.rs:+2:13: +2:14 scope 2 { @@ -16,7 +17,7 @@ fn droppy() -> () { } } scope 4 { - debug z => _5; // in scope 4 at $DIR/enum_cast.rs:+7:9: +7:10 + debug z => _6; // in scope 4 at $DIR/enum_cast.rs:+7:9: +7:10 } bb0: { @@ -25,30 +26,41 @@ fn droppy() -> () { _2 = Droppy::C; // scope 0 at $DIR/enum_cast.rs:+2:17: +2:26 FakeRead(ForLet(None), _2); // scope 0 at $DIR/enum_cast.rs:+2:13: +2:14 StorageLive(_3); // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14 - _4 = discriminant(_2); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27 - _3 = move _4 as usize (IntToInt); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27 + StorageLive(_4); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18 + _4 = move _2; // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18 + _5 = discriminant(_4); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27 + _3 = move _5 as usize (IntToInt); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27 + drop(_4) -> [return: bb1, unwind: bb4]; // scope 3 at $DIR/enum_cast.rs:+5:26: +5:27 + } + + bb1: { + StorageDead(_4); // scope 3 at $DIR/enum_cast.rs:+5:26: +5:27 FakeRead(ForLet(None), _3); // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14 _1 = const (); // scope 0 at $DIR/enum_cast.rs:+1:5: +6:6 StorageDead(_3); // scope 1 at $DIR/enum_cast.rs:+6:5: +6:6 - drop(_2) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6 + drop(_2) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6 } - bb1: { + bb2: { StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6 StorageDead(_1); // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6 - StorageLive(_5); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10 - _5 = Droppy::B; // scope 0 at $DIR/enum_cast.rs:+7:13: +7:22 - FakeRead(ForLet(None), _5); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10 + StorageLive(_6); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10 + _6 = Droppy::B; // scope 0 at $DIR/enum_cast.rs:+7:13: +7:22 + FakeRead(ForLet(None), _6); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10 _0 = const (); // scope 0 at $DIR/enum_cast.rs:+0:13: +8:2 - drop(_5) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2 + drop(_6) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2 } - bb2: { - StorageDead(_5); // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2 + bb3: { + StorageDead(_6); // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2 return; // scope 0 at $DIR/enum_cast.rs:+8:2: +8:2 } - bb3 (cleanup): { + bb4 (cleanup): { + drop(_2) -> bb5; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6 + } + + bb5 (cleanup): { resume; // scope 0 at $DIR/enum_cast.rs:+0:1: +8:2 } } diff --git a/src/test/mir-opt/enum_cast.foo.mir_map.0.mir b/src/test/mir-opt/enum_cast.foo.mir_map.0.mir index 9e44d9158e02f..a1d29a0b90320 100644 --- a/src/test/mir-opt/enum_cast.foo.mir_map.0.mir +++ b/src/test/mir-opt/enum_cast.foo.mir_map.0.mir @@ -3,11 +3,15 @@ fn foo(_1: Foo) -> usize { debug foo => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11 let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26 - let mut _2: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let _2: Foo; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + let mut _3: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 bb0: { - _2 = discriminant(_1); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 - _0 = move _2 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8 + _3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17 + StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17 return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2 } } From 4a25a49edfcca0392a9731df351f1a1229a6e662 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Thu, 13 Oct 2022 17:46:33 +0100 Subject: [PATCH 11/12] Fix test --- src/test/run-pass-valgrind/cast-enum-with-dtor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs index f29bc50e84c4e..f7ef92df8fbec 100644 --- a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs +++ b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs @@ -28,7 +28,7 @@ fn main() { { let e = E::C; assert_eq!(e as u32, 2); - assert_eq!(FLAG.load(Ordering::SeqCst), 0); + assert_eq!(FLAG.load(Ordering::SeqCst), 1); } assert_eq!(FLAG.load(Ordering::SeqCst), 1); } From 2214748adeb74a95405422e766004fd380e41abe Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 13 Oct 2022 22:05:24 +0200 Subject: [PATCH 12/12] Add links to relevant pages to find constraint information --- compiler/rustc_codegen_llvm/src/asm.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index e723187ff1f6d..017513721b75b 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -551,6 +551,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> format!("{{{}}}", reg.name()) } } + // The constraints can be retrieved from + // https://llvm.org/docs/LangRef.html#supported-constraint-code-list InlineAsmRegOrRegClass::RegClass(reg) => match reg { InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => "r", InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) => "w", @@ -624,6 +626,8 @@ fn modifier_to_llvm( reg: InlineAsmRegClass, modifier: Option, ) -> Option { + // The modifiers can be retrieved from + // https://llvm.org/docs/LangRef.html#asm-template-argument-modifiers match reg { InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => modifier, InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg)