From 433439e4eb5db9edd07c46f4cdceff64ea21edcd Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 27 Sep 2021 13:05:44 -0700 Subject: [PATCH 01/11] Make std::thread::available_concurrency support process-limited number of CPUs Use libc::sched_getaffinity and count the number of CPUs in the returned mask. This handles cases where the process doesn't have access to all CPUs, such as when limited via taskset or similar. --- library/std/src/sys/unix/thread.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index 133ad3ea420b8..cff4ba47357c7 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -275,6 +275,14 @@ pub fn available_concurrency() -> io::Result { target_os = "solaris", target_os = "illumos", ))] { + #[cfg(any(target_os = "android", target_os = "linux"))] + { + let mut set: libc::cpu_set_t = unsafe { mem::zeroed() }; + if unsafe { libc::sched_getaffinity(0, mem::size_of::(), &mut set) } == 0 { + let count = unsafe { libc::CPU_COUNT(&set) }; + return Ok(unsafe { NonZeroUsize::new_unchecked(count as usize) }); + } + } match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } { -1 => Err(io::Error::last_os_error()), 0 => Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")), From 11140ff1a0dd3a395dd3ca1488bf580559f782f8 Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Mon, 4 Oct 2021 01:04:17 -0400 Subject: [PATCH 02/11] Stabilize `unreachable_unchecked` as `const fn` --- library/core/src/hint.rs | 2 +- library/core/src/intrinsics.rs | 2 +- library/core/src/lib.rs | 1 - src/test/ui/consts/const_unsafe_unreachable.rs | 4 +--- src/test/ui/consts/const_unsafe_unreachable_ub.rs | 3 +-- src/test/ui/consts/const_unsafe_unreachable_ub.stderr | 6 +++--- 6 files changed, 7 insertions(+), 11 deletions(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 1c3afcdaa69e9..95798879155c5 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -44,7 +44,7 @@ use crate::intrinsics; /// ``` #[inline] #[stable(feature = "unreachable", since = "1.27.0")] -#[rustc_const_unstable(feature = "const_unreachable_unchecked", issue = "53188")] +#[rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")] pub const unsafe fn unreachable_unchecked() -> ! { // SAFETY: the safety contract for `intrinsics::unreachable` must // be upheld by the caller. diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 3e26d46ddcaf9..067a27fed4142 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -735,7 +735,7 @@ extern "rust-intrinsic" { /// reach code marked with this function. /// /// The stabilized version of this intrinsic is [`core::hint::unreachable_unchecked`]. - #[rustc_const_unstable(feature = "const_unreachable_unchecked", issue = "53188")] + #[rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")] pub fn unreachable() -> !; /// Informs the optimizer that a condition is always true. diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 2230461b5f4b5..9a966cc51280a 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -103,7 +103,6 @@ #![feature(const_trait_impl)] #![feature(const_type_id)] #![feature(const_type_name)] -#![feature(const_unreachable_unchecked)] #![feature(const_default_impls)] #![feature(duration_consts_2)] #![feature(ptr_metadata)] diff --git a/src/test/ui/consts/const_unsafe_unreachable.rs b/src/test/ui/consts/const_unsafe_unreachable.rs index 1fec491ca95b1..1c3baec5d8638 100644 --- a/src/test/ui/consts/const_unsafe_unreachable.rs +++ b/src/test/ui/consts/const_unsafe_unreachable.rs @@ -1,7 +1,5 @@ // run-pass -#![feature(const_unreachable_unchecked)] - const unsafe fn foo(x: bool) -> bool { match x { true => true, @@ -12,5 +10,5 @@ const unsafe fn foo(x: bool) -> bool { const BAR: bool = unsafe { foo(true) }; fn main() { - assert_eq!(BAR, true); + assert_eq!(BAR, true); } diff --git a/src/test/ui/consts/const_unsafe_unreachable_ub.rs b/src/test/ui/consts/const_unsafe_unreachable_ub.rs index 8cee5b5065136..b418fea617cea 100644 --- a/src/test/ui/consts/const_unsafe_unreachable_ub.rs +++ b/src/test/ui/consts/const_unsafe_unreachable_ub.rs @@ -1,5 +1,4 @@ // error-pattern: evaluation of constant value failed -#![feature(const_unreachable_unchecked)] const unsafe fn foo(x: bool) -> bool { match x { @@ -11,5 +10,5 @@ const unsafe fn foo(x: bool) -> bool { const BAR: bool = unsafe { foo(false) }; fn main() { - assert_eq!(BAR, true); + assert_eq!(BAR, true); } diff --git a/src/test/ui/consts/const_unsafe_unreachable_ub.stderr b/src/test/ui/consts/const_unsafe_unreachable_ub.stderr index 65cb3d74b233e..ec6ce1f5d7c08 100644 --- a/src/test/ui/consts/const_unsafe_unreachable_ub.stderr +++ b/src/test/ui/consts/const_unsafe_unreachable_ub.stderr @@ -7,13 +7,13 @@ LL | unsafe { intrinsics::unreachable() } | entering unreachable code | inside `unreachable_unchecked` at $SRC_DIR/core/src/hint.rs:LL:COL | - ::: $DIR/const_unsafe_unreachable_ub.rs:7:18 + ::: $DIR/const_unsafe_unreachable_ub.rs:6:18 | LL | false => std::hint::unreachable_unchecked(), - | ---------------------------------- inside `foo` at $DIR/const_unsafe_unreachable_ub.rs:7:18 + | ---------------------------------- inside `foo` at $DIR/const_unsafe_unreachable_ub.rs:6:18 ... LL | const BAR: bool = unsafe { foo(false) }; - | ---------- inside `BAR` at $DIR/const_unsafe_unreachable_ub.rs:11:28 + | ---------- inside `BAR` at $DIR/const_unsafe_unreachable_ub.rs:10:28 error: aborting due to previous error From 8007dfa3b2af8f9de8cf3568ac6b3770fd9e5afd Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Fri, 15 Oct 2021 01:41:31 +0200 Subject: [PATCH 03/11] Remove alloc::prelude As per the libs team decision in #58935. Closes #58935 --- .../example/alloc_example.rs | 4 ++-- .../rustc_codegen_gcc/example/alloc_example.rs | 4 ++-- library/alloc/src/lib.rs | 1 - library/alloc/src/prelude/mod.rs | 15 --------------- library/alloc/src/prelude/v1.rs | 14 -------------- 5 files changed, 4 insertions(+), 34 deletions(-) delete mode 100644 library/alloc/src/prelude/mod.rs delete mode 100644 library/alloc/src/prelude/v1.rs diff --git a/compiler/rustc_codegen_cranelift/example/alloc_example.rs b/compiler/rustc_codegen_cranelift/example/alloc_example.rs index d0d492e96742d..bc1594d82ecf9 100644 --- a/compiler/rustc_codegen_cranelift/example/alloc_example.rs +++ b/compiler/rustc_codegen_cranelift/example/alloc_example.rs @@ -1,10 +1,10 @@ -#![feature(start, core_intrinsics, alloc_prelude, alloc_error_handler, box_syntax)] +#![feature(start, core_intrinsics, alloc_error_handler, box_syntax)] #![no_std] extern crate alloc; extern crate alloc_system; -use alloc::prelude::v1::*; +use alloc::boxed::Box; use alloc_system::System; diff --git a/compiler/rustc_codegen_gcc/example/alloc_example.rs b/compiler/rustc_codegen_gcc/example/alloc_example.rs index bc6dd007ba010..74ea7ec4ede69 100644 --- a/compiler/rustc_codegen_gcc/example/alloc_example.rs +++ b/compiler/rustc_codegen_gcc/example/alloc_example.rs @@ -1,10 +1,10 @@ -#![feature(start, box_syntax, core_intrinsics, alloc_prelude, alloc_error_handler)] +#![feature(start, box_syntax, core_intrinsics, alloc_error_handler)] #![no_std] extern crate alloc; extern crate alloc_system; -use alloc::prelude::v1::*; +use alloc::boxed::Box; use alloc_system::System; diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index e86c41b1ff887..635708fd4cf6e 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -189,7 +189,6 @@ mod boxed { pub mod borrow; pub mod collections; pub mod fmt; -pub mod prelude; pub mod raw_vec; pub mod rc; pub mod slice; diff --git a/library/alloc/src/prelude/mod.rs b/library/alloc/src/prelude/mod.rs deleted file mode 100644 index 0534ad3edc79d..0000000000000 --- a/library/alloc/src/prelude/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -//! The alloc Prelude -//! -//! The purpose of this module is to alleviate imports of commonly-used -//! items of the `alloc` crate by adding a glob import to the top of modules: -//! -//! ``` -//! # #![allow(unused_imports)] -//! #![feature(alloc_prelude)] -//! extern crate alloc; -//! use alloc::prelude::v1::*; -//! ``` - -#![unstable(feature = "alloc_prelude", issue = "58935")] - -pub mod v1; diff --git a/library/alloc/src/prelude/v1.rs b/library/alloc/src/prelude/v1.rs deleted file mode 100644 index 6a53b4ca1f6ca..0000000000000 --- a/library/alloc/src/prelude/v1.rs +++ /dev/null @@ -1,14 +0,0 @@ -//! The first version of the prelude of `alloc` crate. -//! -//! See the [module-level documentation](../index.html) for more. - -#![unstable(feature = "alloc_prelude", issue = "58935")] - -#[unstable(feature = "alloc_prelude", issue = "58935")] -pub use crate::borrow::ToOwned; -#[unstable(feature = "alloc_prelude", issue = "58935")] -pub use crate::boxed::Box; -#[unstable(feature = "alloc_prelude", issue = "58935")] -pub use crate::string::{String, ToString}; -#[unstable(feature = "alloc_prelude", issue = "58935")] -pub use crate::vec::Vec; From 43f4ef5c6a059c32e19483ff3d295feb2f37c5b8 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Fri, 15 Oct 2021 12:27:42 +0300 Subject: [PATCH 04/11] Moved format-version constant to rustdoc-json-types --- src/librustdoc/json/mod.rs | 2 +- src/rustdoc-json-types/lib.rs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 637e5f2288d62..0031e3915fa40 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -255,7 +255,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { ) }) .collect(), - format_version: 9, + format_version: types::FORMAT_VERSION, }; let mut p = self.out_path.clone(); p.push(output.index.get(&output.root).unwrap().name.clone().unwrap()); diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 7c418697c1c1c..9466f84ffcd59 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -510,5 +510,8 @@ pub struct Static { pub expr: String, } +/// rustdoc format-version. +pub const FORMAT_VERSION: u32 = 9; + #[cfg(test)] mod tests; From d2dc0f3b0f0267941b47bde7bd48d26b2c22ca6a Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 15 Oct 2021 14:48:57 +0000 Subject: [PATCH 05/11] emitter: current substitution can be multi-line In `splice_lines`, there is some arithmetic to compute the required alignment such that future substitutions in a suggestion are aligned correctly. However, this assumed that the current substitution's span was only on a single line. In circumstances where this was not true, it could result in a arithmetic overflow when the substitution's end column was less than the substitution's start column. Signed-off-by: David Wood --- compiler/rustc_errors/src/lib.rs | 2 +- ...sue-89280-emitter-overflow-splice-lines.rs | 10 ++++++++ ...89280-emitter-overflow-splice-lines.stderr | 23 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.rs create mode 100644 src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 60a48b5a2d9c1..9b2094adb150c 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -341,7 +341,7 @@ impl CodeSuggestion { }); buf.push_str(&part.snippet); let cur_hi = sm.lookup_char_pos(part.span.hi()); - if prev_hi.line == cur_lo.line { + if prev_hi.line == cur_lo.line && cur_hi.line == cur_lo.line { // Account for the difference between the width of the current code and the // snippet being suggested, so that the *later* suggestions are correctly // aligned on the screen. diff --git a/src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.rs b/src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.rs new file mode 100644 index 0000000000000..a1c7af128d2ee --- /dev/null +++ b/src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.rs @@ -0,0 +1,10 @@ +// check-pass + +trait X { + fn test(x: u32, ( +//~^ WARN anonymous parameters are deprecated and will be removed in the next edition +//~^^ WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + )) {} +} + +fn main() {} diff --git a/src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr b/src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr new file mode 100644 index 0000000000000..4ec78a298fe62 --- /dev/null +++ b/src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr @@ -0,0 +1,23 @@ +warning: anonymous parameters are deprecated and will be removed in the next edition + --> $DIR/issue-89280-emitter-overflow-splice-lines.rs:4:21 + | +LL | fn test(x: u32, ( + | _____________________^ +LL | | +LL | | +LL | | )) {} + | |_____^ + | + = note: `#[warn(anonymous_parameters)]` on by default + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #41686 +help: try naming the parameter or explicitly ignoring it + | +LL ~ fn test(x: u32, _: ( +LL + +LL + +LL ~ )) {} + | + +warning: 1 warning emitted + From c4f9eb1e5a6ab0f1eaf36170b083e28946c69e15 Mon Sep 17 00:00:00 2001 From: jackh726 Date: Tue, 5 Oct 2021 17:43:45 -0400 Subject: [PATCH 06/11] Emit impl difference error for GenericBoundFailure too --- .../nice_region_error/trait_impl_difference.rs | 4 +++- .../ui/generic-associated-types/impl_bounds.rs | 2 +- .../generic-associated-types/impl_bounds.stderr | 12 ++++++------ .../ui/generic-associated-types/issue-86787.rs | 4 ++-- .../generic-associated-types/issue-86787.stderr | 17 ++++++++++------- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs index 0efe5a56436b5..ea9d0eae17e2c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -46,7 +46,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } } } - if let RegionResolutionError::ConcreteFailure(origin, _, _) = error.clone() { + if let RegionResolutionError::ConcreteFailure(origin, _, _) + | RegionResolutionError::GenericBoundFailure(origin, _, _) = error.clone() + { if let SubregionOrigin::CompareImplTypeObligation { span, item_name, diff --git a/src/test/ui/generic-associated-types/impl_bounds.rs b/src/test/ui/generic-associated-types/impl_bounds.rs index 27c135cb7cf82..ff2ffec22c456 100644 --- a/src/test/ui/generic-associated-types/impl_bounds.rs +++ b/src/test/ui/generic-associated-types/impl_bounds.rs @@ -13,7 +13,7 @@ struct Fooy(T); impl Foo for Fooy { type A<'a> where Self: 'static = (&'a ()); - //~^ ERROR the parameter type `T` may not live long enough + //~^ ERROR `impl` associated type type B<'a, 'b> where 'b: 'a = (&'a(), &'b ()); //~^ ERROR `impl` associated type //~| ERROR lifetime bound not satisfied diff --git a/src/test/ui/generic-associated-types/impl_bounds.stderr b/src/test/ui/generic-associated-types/impl_bounds.stderr index 649eadec515d0..f47b5f81e25b2 100644 --- a/src/test/ui/generic-associated-types/impl_bounds.stderr +++ b/src/test/ui/generic-associated-types/impl_bounds.stderr @@ -1,11 +1,11 @@ -error[E0310]: the parameter type `T` may not live long enough +error: `impl` associated type signature for `A` doesn't match `trait` associated type signature --> $DIR/impl_bounds.rs:15:5 | +LL | type A<'a> where Self: 'a; + | -------------------------- expected +... LL | type A<'a> where Self: 'static = (&'a ()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider adding an explicit lifetime bound `T: 'static`... - = note: ...so that the definition in impl matches the definition from the trait + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found error: `impl` associated type signature for `B` doesn't match `trait` associated type signature --> $DIR/impl_bounds.rs:17:5 @@ -85,5 +85,5 @@ LL | impl Foo for Fooy { error: aborting due to 5 previous errors -Some errors have detailed explanations: E0277, E0310, E0478. +Some errors have detailed explanations: E0277, E0478. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/generic-associated-types/issue-86787.rs b/src/test/ui/generic-associated-types/issue-86787.rs index 57d478a9ef1e3..f1f05ea6627e8 100644 --- a/src/test/ui/generic-associated-types/issue-86787.rs +++ b/src/test/ui/generic-associated-types/issue-86787.rs @@ -21,8 +21,8 @@ where { type T = Either; type TRef<'a> - //~^ the associated type - //~^^ the associated type + //~^ `impl` associated type signature + //~^^ `impl` associated type signature where ::T: 'a, ::T: 'a diff --git a/src/test/ui/generic-associated-types/issue-86787.stderr b/src/test/ui/generic-associated-types/issue-86787.stderr index e1ff772921104..648eff77d73bb 100644 --- a/src/test/ui/generic-associated-types/issue-86787.stderr +++ b/src/test/ui/generic-associated-types/issue-86787.stderr @@ -1,29 +1,32 @@ -error[E0309]: the associated type `::T` may not live long enough +error: `impl` associated type signature for `TRef` doesn't match `trait` associated type signature --> $DIR/issue-86787.rs:23:5 | +LL | type TRef<'a>; + | -------------- expected +... LL | / type TRef<'a> LL | | LL | | LL | | where LL | | ::T: 'a, LL | | ::T: 'a - | | - help: consider adding a where clause: `, ::T: 'a` LL | | = Either<&'a Left::T, &'a Right::T>; - | |________________________________________^ ...so that the definition in impl matches the definition from the trait + | |________________________________________^ found -error[E0309]: the associated type `::T` may not live long enough +error: `impl` associated type signature for `TRef` doesn't match `trait` associated type signature --> $DIR/issue-86787.rs:23:5 | +LL | type TRef<'a>; + | -------------- expected +... LL | / type TRef<'a> LL | | LL | | LL | | where LL | | ::T: 'a, LL | | ::T: 'a - | | - help: consider adding a where clause: `, ::T: 'a` LL | | = Either<&'a Left::T, &'a Right::T>; - | |________________________________________^ ...so that the definition in impl matches the definition from the trait + | |________________________________________^ found error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0309`. From a7c132de559ee904ec59d8305d0e9c4ef6d822b1 Mon Sep 17 00:00:00 2001 From: jackh726 Date: Fri, 8 Oct 2021 22:55:06 -0400 Subject: [PATCH 07/11] Move push_outlives_components to rustc_infer --- .../src/infer/outlives/components.rs} | 24 ++++++++++--------- .../rustc_infer/src/infer/outlives/mod.rs | 1 + .../src/infer/outlives/obligations.rs | 6 ++--- compiler/rustc_infer/src/traits/util.rs | 4 ++-- compiler/rustc_middle/src/ty/mod.rs | 1 - .../src/implied_outlives_bounds.rs | 4 ++-- compiler/rustc_typeck/src/outlives/utils.rs | 4 ++-- 7 files changed, 23 insertions(+), 21 deletions(-) rename compiler/{rustc_middle/src/ty/outlives.rs => rustc_infer/src/infer/outlives/components.rs} (94%) diff --git a/compiler/rustc_middle/src/ty/outlives.rs b/compiler/rustc_infer/src/infer/outlives/components.rs similarity index 94% rename from compiler/rustc_middle/src/ty/outlives.rs rename to compiler/rustc_infer/src/infer/outlives/components.rs index ef4ad998f10c8..98f926e9d76d5 100644 --- a/compiler/rustc_middle/src/ty/outlives.rs +++ b/compiler/rustc_infer/src/infer/outlives/components.rs @@ -2,10 +2,10 @@ // refers to rules defined in RFC 1214 (`OutlivesFooBar`), so see that // RFC for reference. -use crate::ty::subst::{GenericArg, GenericArgKind}; -use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_data_structures::sso::SsoHashSet; -use smallvec::SmallVec; +use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; +use smallvec::{smallvec, SmallVec}; #[derive(Debug)] pub enum Component<'tcx> { @@ -47,14 +47,16 @@ pub enum Component<'tcx> { EscapingProjection(Vec>), } -impl<'tcx> TyCtxt<'tcx> { - /// Push onto `out` all the things that must outlive `'a` for the condition - /// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**. - pub fn push_outlives_components(self, ty0: Ty<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>) { - let mut visited = SsoHashSet::new(); - compute_components(self, ty0, out, &mut visited); - debug!("components({:?}) = {:?}", ty0, out); - } +/// Push onto `out` all the things that must outlive `'a` for the condition +/// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**. +pub fn push_outlives_components( + tcx: TyCtxt<'tcx>, + ty0: Ty<'tcx>, + out: &mut SmallVec<[Component<'tcx>; 4]>, +) { + let mut visited = SsoHashSet::new(); + compute_components(tcx, ty0, out, &mut visited); + debug!("components({:?}) = {:?}", ty0, out); } fn compute_components( diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 4dd5e8ba54500..03d6c45a65345 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -1,5 +1,6 @@ //! Various code related to computing outlives relations. +pub mod components; pub mod env; pub mod obligations; pub mod verify; diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 437083c68dcec..91a22ecc5a994 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -1,5 +1,5 @@ //! Code that handles "type-outlives" constraints like `T: 'a`. This -//! is based on the `push_outlives_components` function defined on the tcx, +//! is based on the `push_outlives_components` function defined in rustc_infer, //! but it adds a bit of heuristics on top, in particular to deal with //! associated types and projections. //! @@ -59,13 +59,13 @@ //! might later infer `?U` to something like `&'b u32`, which would //! imply that `'b: 'a`. +use crate::infer::outlives::components::{push_outlives_components, Component}; use crate::infer::outlives::env::RegionBoundPairs; use crate::infer::outlives::verify::VerifyBoundCx; use crate::infer::{ self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, UndoLog, VerifyBound, }; use crate::traits::{ObligationCause, ObligationCauseCode}; -use rustc_middle::ty::outlives::Component; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{self, Region, Ty, TyCtxt, TypeFoldable}; @@ -271,7 +271,7 @@ where assert!(!ty.has_escaping_bound_vars()); let mut components = smallvec![]; - self.tcx.push_outlives_components(ty, &mut components); + push_outlives_components(self.tcx, ty, &mut components); self.components_must_outlive(origin, &components, region); } diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 30d5613d5820d..c839f824d1c9c 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -1,8 +1,8 @@ use smallvec::smallvec; +use crate::infer::outlives::components::{push_outlives_components, Component}; use crate::traits::{Obligation, ObligationCause, PredicateObligation}; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; -use rustc_middle::ty::outlives::Component; use rustc_middle::ty::{self, ToPredicate, TyCtxt, WithConstness}; use rustc_span::symbol::Ident; @@ -200,7 +200,7 @@ impl Elaborator<'tcx> { let visited = &mut self.visited; let mut components = smallvec![]; - tcx.push_outlives_components(ty_max, &mut components); + push_outlives_components(tcx, ty_max, &mut components); self.stack.extend( components .into_iter() diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 0eacedc09ee6d..20d07bdc48a62 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -92,7 +92,6 @@ pub mod fold; pub mod inhabitedness; pub mod layout; pub mod normalize_erasing_regions; -pub mod outlives; pub mod print; pub mod query; pub mod relate; diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index 1d10d06849062..f2fc4e59d4649 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -4,9 +4,9 @@ use rustc_hir as hir; use rustc_infer::infer::canonical::{self, Canonical}; +use rustc_infer::infer::outlives::components::{push_outlives_components, Component}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::TraitEngineExt as _; -use rustc_middle::ty::outlives::Component; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_span::source_map::DUMMY_SP; @@ -118,7 +118,7 @@ fn compute_implied_outlives_bounds<'tcx>( ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty_a, r_b)) => { let ty_a = infcx.resolve_vars_if_possible(ty_a); let mut components = smallvec![]; - tcx.push_outlives_components(ty_a, &mut components); + push_outlives_components(tcx, ty_a, &mut components); implied_bounds_from_components(r_b, components) } }, diff --git a/compiler/rustc_typeck/src/outlives/utils.rs b/compiler/rustc_typeck/src/outlives/utils.rs index 8b06967879638..76ae2ee43566e 100644 --- a/compiler/rustc_typeck/src/outlives/utils.rs +++ b/compiler/rustc_typeck/src/outlives/utils.rs @@ -1,4 +1,4 @@ -use rustc_middle::ty::outlives::Component; +use rustc_infer::infer::outlives::components::{push_outlives_components, Component}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; use rustc_middle::ty::{self, Region, RegionKind, Ty, TyCtxt}; use rustc_span::Span; @@ -35,7 +35,7 @@ pub fn insert_outlives_predicate<'tcx>( // Or if within `struct Foo` you had `T = Vec`, then // we would want to add `U: 'outlived_region` let mut components = smallvec![]; - tcx.push_outlives_components(ty, &mut components); + push_outlives_components(tcx, ty, &mut components); for component in components { match component { Component::Region(r) => { From d3fa07c72e079e8a72fcb55a792d2f855e80722b Mon Sep 17 00:00:00 2001 From: jackh726 Date: Wed, 13 Oct 2021 22:22:09 -0400 Subject: [PATCH 08/11] Use LocalDefId directly in more places in wfcheck --- compiler/rustc_typeck/src/check/wfcheck.rs | 57 +++++++++------------- 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 20cf9a75e1267..30aab38b1eb85 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -142,23 +142,23 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) { } } hir::ItemKind::Fn(ref sig, ..) => { - check_item_fn(tcx, item.hir_id(), item.ident, item.span, sig.decl); + check_item_fn(tcx, item.def_id, item.ident, item.span, sig.decl); } hir::ItemKind::Static(ty, ..) => { - check_item_type(tcx, item.hir_id(), ty.span, false); + check_item_type(tcx, item.def_id, ty.span, false); } hir::ItemKind::Const(ty, ..) => { - check_item_type(tcx, item.hir_id(), ty.span, false); + check_item_type(tcx, item.def_id, ty.span, false); } hir::ItemKind::ForeignMod { items, .. } => { for it in items.iter() { let it = tcx.hir().foreign_item(it.id); match it.kind { hir::ForeignItemKind::Fn(decl, ..) => { - check_item_fn(tcx, it.hir_id(), it.ident, it.span, decl) + check_item_fn(tcx, it.def_id, it.ident, it.span, decl) } hir::ForeignItemKind::Static(ty, ..) => { - check_item_type(tcx, it.hir_id(), ty.span, true) + check_item_type(tcx, it.def_id, ty.span, true) } hir::ForeignItemKind::Type => (), } @@ -199,7 +199,7 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { _ => (None, trait_item.span), }; check_object_unsafe_self_trait_by_name(tcx, trait_item); - check_associated_item(tcx, trait_item.hir_id(), span, method_sig); + check_associated_item(tcx, trait_item.def_id, span, method_sig); let encl_trait_hir_id = tcx.hir().get_parent_item(hir_id); let encl_trait = tcx.hir().expect_item(encl_trait_hir_id); @@ -327,7 +327,7 @@ pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { _ => (None, impl_item.span), }; - check_associated_item(tcx, impl_item.hir_id(), span, method_sig); + check_associated_item(tcx, impl_item.def_id, span, method_sig); } fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { @@ -437,13 +437,13 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { #[tracing::instrument(level = "debug", skip(tcx, span, sig_if_method))] fn check_associated_item( tcx: TyCtxt<'_>, - item_id: hir::HirId, + item_id: LocalDefId, span: Span, sig_if_method: Option<&hir::FnSig<'_>>, ) { - let code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(item_id.expect_owner()))); + let code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(item_id))); for_id(tcx, item_id, span).with_fcx(|fcx| { - let item = fcx.tcx.associated_item(fcx.tcx.hir().local_def_id(item_id)); + let item = fcx.tcx.associated_item(item_id); let (mut implied_bounds, self_ty) = match item.container { ty::TraitContainer(_) => (FxHashSet::default(), fcx.tcx.types.self_param), @@ -455,11 +455,7 @@ fn check_associated_item( match item.kind { ty::AssocKind::Const => { let ty = fcx.tcx.type_of(item.def_id); - let ty = fcx.normalize_associated_types_in_wf( - span, - ty, - WellFormedLoc::Ty(item_id.expect_owner()), - ); + let ty = fcx.normalize_associated_types_in_wf(span, ty, WellFormedLoc::Ty(item_id)); fcx.register_wf_obligation(ty.into(), span, code.clone()); } ty::AssocKind::Fn => { @@ -481,11 +477,8 @@ fn check_associated_item( } if item.defaultness.has_value() { let ty = fcx.tcx.type_of(item.def_id); - let ty = fcx.normalize_associated_types_in_wf( - span, - ty, - WellFormedLoc::Ty(item_id.expect_owner()), - ); + let ty = + fcx.normalize_associated_types_in_wf(span, ty, WellFormedLoc::Ty(item_id)); fcx.register_wf_obligation(ty.into(), span, code.clone()); } } @@ -496,14 +489,13 @@ fn check_associated_item( } fn for_item<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'_>) -> CheckWfFcxBuilder<'tcx> { - for_id(tcx, item.hir_id(), item.span) + for_id(tcx, item.def_id, item.span) } -fn for_id(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) -> CheckWfFcxBuilder<'_> { - let def_id = tcx.hir().local_def_id(id); +fn for_id(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) -> CheckWfFcxBuilder<'_> { CheckWfFcxBuilder { inherited: Inherited::build(tcx, def_id), - id, + id: hir::HirId::make_owner(def_id), span, param_env: tcx.param_env(def_id), } @@ -665,13 +657,12 @@ fn check_associated_type_bounds(fcx: &FnCtxt<'_, '_>, item: &ty::AssocItem, span fn check_item_fn( tcx: TyCtxt<'_>, - item_id: hir::HirId, + def_id: LocalDefId, ident: Ident, span: Span, decl: &hir::FnDecl<'_>, ) { - for_id(tcx, item_id, span).with_fcx(|fcx| { - let def_id = tcx.hir().local_def_id(item_id); + for_id(tcx, def_id, span).with_fcx(|fcx| { let sig = tcx.fn_sig(def_id); let mut implied_bounds = FxHashSet::default(); check_fn_or_method(fcx, ident.span, sig, decl, def_id.to_def_id(), &mut implied_bounds); @@ -679,16 +670,12 @@ fn check_item_fn( }) } -fn check_item_type(tcx: TyCtxt<'_>, item_id: hir::HirId, ty_span: Span, allow_foreign_ty: bool) { +fn check_item_type(tcx: TyCtxt<'_>, item_id: LocalDefId, ty_span: Span, allow_foreign_ty: bool) { debug!("check_item_type: {:?}", item_id); for_id(tcx, item_id, ty_span).with_fcx(|fcx| { - let ty = tcx.type_of(tcx.hir().local_def_id(item_id)); - let item_ty = fcx.normalize_associated_types_in_wf( - ty_span, - ty, - WellFormedLoc::Ty(item_id.expect_owner()), - ); + let ty = tcx.type_of(item_id); + let item_ty = fcx.normalize_associated_types_in_wf(ty_span, ty, WellFormedLoc::Ty(item_id)); let mut forbid_unsized = true; if allow_foreign_ty { @@ -701,7 +688,7 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: hir::HirId, ty_span: Span, allow_fo fcx.register_wf_obligation( item_ty.into(), ty_span, - ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(item_id.expect_owner()))), + ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(item_id))), ); if forbid_unsized { fcx.register_bound( From 2b5b456e23b61ccd36732046134d17ebe2152e7d Mon Sep 17 00:00:00 2001 From: jackh726 Date: Fri, 15 Oct 2021 11:31:22 -0400 Subject: [PATCH 09/11] Move some outlives bounds things from rustc_trait_selection to rustc_typeck --- compiler/rustc_trait_selection/src/infer.rs | 49 ------------------ .../src/traits/query/mod.rs | 1 - .../query/type_op/implied_outlives_bounds.rs | 2 +- .../src/implied_outlives_bounds.rs | 2 +- compiler/rustc_typeck/src/check/regionck.rs | 51 +++++++++++++++++-- compiler/rustc_typeck/src/outlives/mod.rs | 1 + .../src/outlives}/outlives_bounds.rs | 8 +-- 7 files changed, 55 insertions(+), 59 deletions(-) rename compiler/{rustc_trait_selection/src/traits/query => rustc_typeck/src/outlives}/outlives_bounds.rs (93%) diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 8fb4eb641c26a..70816b5722b2d 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -1,12 +1,8 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -use crate::traits::query::outlives_bounds::InferCtxtExt as _; use crate::traits::{self, TraitEngine, TraitEngineExt}; -use rustc_data_structures::stable_set::FxHashSet; -use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; -use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::traits::ObligationCause; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::infer::canonical::{Canonical, CanonicalizedQueryResponse, QueryResponse}; @@ -180,48 +176,3 @@ impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> { ) } } - -pub trait OutlivesEnvironmentExt<'tcx> { - fn add_implied_bounds( - &mut self, - infcx: &InferCtxt<'a, 'tcx>, - fn_sig_tys: FxHashSet>, - body_id: hir::HirId, - span: Span, - ); -} - -impl<'tcx> OutlivesEnvironmentExt<'tcx> for OutlivesEnvironment<'tcx> { - /// This method adds "implied bounds" into the outlives environment. - /// Implied bounds are outlives relationships that we can deduce - /// on the basis that certain types must be well-formed -- these are - /// either the types that appear in the function signature or else - /// the input types to an impl. For example, if you have a function - /// like - /// - /// ``` - /// fn foo<'a, 'b, T>(x: &'a &'b [T]) { } - /// ``` - /// - /// we can assume in the caller's body that `'b: 'a` and that `T: - /// 'b` (and hence, transitively, that `T: 'a`). This method would - /// add those assumptions into the outlives-environment. - /// - /// Tests: `src/test/ui/regions/regions-free-region-ordering-*.rs` - fn add_implied_bounds( - &mut self, - infcx: &InferCtxt<'a, 'tcx>, - fn_sig_tys: FxHashSet>, - body_id: hir::HirId, - span: Span, - ) { - debug!("add_implied_bounds()"); - - for ty in fn_sig_tys { - let ty = infcx.resolve_vars_if_possible(ty); - debug!("add_implied_bounds: ty = {}", ty); - let implied_bounds = infcx.implied_outlives_bounds(self.param_env, body_id, ty, span); - self.add_outlives_bounds(Some(infcx), implied_bounds) - } - } -} diff --git a/compiler/rustc_trait_selection/src/traits/query/mod.rs b/compiler/rustc_trait_selection/src/traits/query/mod.rs index f6f42814d3f07..ef3493678131f 100644 --- a/compiler/rustc_trait_selection/src/traits/query/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/mod.rs @@ -9,7 +9,6 @@ pub mod dropck_outlives; pub mod evaluate_obligation; pub mod method_autoderef; pub mod normalize; -pub mod outlives_bounds; pub mod type_op; pub use rustc_middle::traits::query::*; diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index 03087e3353a6e..04c382d439d4c 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -1,6 +1,6 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; -use crate::traits::query::outlives_bounds::OutlivesBound; use crate::traits::query::Fallible; +use rustc_infer::traits::query::OutlivesBound; use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt}; #[derive(Copy, Clone, Debug, HashStable, TypeFoldable, Lift)] diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index f2fc4e59d4649..37e007337374f 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -6,12 +6,12 @@ use rustc_hir as hir; use rustc_infer::infer::canonical::{self, Canonical}; use rustc_infer::infer::outlives::components::{push_outlives_components, Component}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; +use rustc_infer::traits::query::OutlivesBound; use rustc_infer::traits::TraitEngineExt as _; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_span::source_map::DUMMY_SP; use rustc_trait_selection::infer::InferCtxtBuilderExt; -use rustc_trait_selection::traits::query::outlives_bounds::OutlivesBound; use rustc_trait_selection::traits::query::{CanonicalTyGoal, Fallible, NoSolution}; use rustc_trait_selection::traits::wf; use rustc_trait_selection::traits::FulfillmentContext; diff --git a/compiler/rustc_typeck/src/check/regionck.rs b/compiler/rustc_typeck/src/check/regionck.rs index 79443010fbb3d..7c8b75271871a 100644 --- a/compiler/rustc_typeck/src/check/regionck.rs +++ b/compiler/rustc_typeck/src/check/regionck.rs @@ -76,19 +76,19 @@ use crate::check::dropck; use crate::check::FnCtxt; use crate::mem_categorization as mc; use crate::middle::region; +use crate::outlives::outlives_bounds::InferCtxtExt as _; use rustc_data_structures::stable_set::FxHashSet; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::PatKind; use rustc_infer::infer::outlives::env::OutlivesEnvironment; -use rustc_infer::infer::{self, RegionObligation, RegionckMode}; +use rustc_infer::infer::{self, InferCtxt, RegionObligation, RegionckMode}; use rustc_middle::hir::place::{PlaceBase, PlaceWithHirId}; use rustc_middle::ty::adjustment; use rustc_middle::ty::{self, Ty}; use rustc_span::Span; -use rustc_trait_selection::infer::OutlivesEnvironmentExt; -use rustc_trait_selection::opaque_types::InferCtxtExt; +use rustc_trait_selection::opaque_types::InferCtxtExt as _; use std::ops::Deref; // a variation on try that just returns unit @@ -104,6 +104,51 @@ macro_rules! ignore_err { }; } +trait OutlivesEnvironmentExt<'tcx> { + fn add_implied_bounds( + &mut self, + infcx: &InferCtxt<'a, 'tcx>, + fn_sig_tys: FxHashSet>, + body_id: hir::HirId, + span: Span, + ); +} + +impl<'tcx> OutlivesEnvironmentExt<'tcx> for OutlivesEnvironment<'tcx> { + /// This method adds "implied bounds" into the outlives environment. + /// Implied bounds are outlives relationships that we can deduce + /// on the basis that certain types must be well-formed -- these are + /// either the types that appear in the function signature or else + /// the input types to an impl. For example, if you have a function + /// like + /// + /// ``` + /// fn foo<'a, 'b, T>(x: &'a &'b [T]) { } + /// ``` + /// + /// we can assume in the caller's body that `'b: 'a` and that `T: + /// 'b` (and hence, transitively, that `T: 'a`). This method would + /// add those assumptions into the outlives-environment. + /// + /// Tests: `src/test/ui/regions/regions-free-region-ordering-*.rs` + fn add_implied_bounds( + &mut self, + infcx: &InferCtxt<'a, 'tcx>, + fn_sig_tys: FxHashSet>, + body_id: hir::HirId, + span: Span, + ) { + debug!("add_implied_bounds()"); + + for ty in fn_sig_tys { + let ty = infcx.resolve_vars_if_possible(ty); + debug!("add_implied_bounds: ty = {}", ty); + let implied_bounds = infcx.implied_outlives_bounds(self.param_env, body_id, ty, span); + self.add_outlives_bounds(Some(infcx), implied_bounds) + } + } +} + /////////////////////////////////////////////////////////////////////////// // PUBLIC ENTRY POINTS diff --git a/compiler/rustc_typeck/src/outlives/mod.rs b/compiler/rustc_typeck/src/outlives/mod.rs index 957ff2525190d..eb3853b6b3dee 100644 --- a/compiler/rustc_typeck/src/outlives/mod.rs +++ b/compiler/rustc_typeck/src/outlives/mod.rs @@ -9,6 +9,7 @@ use rustc_span::Span; mod explicit; mod implicit_infer; +crate mod outlives_bounds; /// Code to write unit test for outlives. pub mod test; mod utils; diff --git a/compiler/rustc_trait_selection/src/traits/query/outlives_bounds.rs b/compiler/rustc_typeck/src/outlives/outlives_bounds.rs similarity index 93% rename from compiler/rustc_trait_selection/src/traits/query/outlives_bounds.rs rename to compiler/rustc_typeck/src/outlives/outlives_bounds.rs index f5fa52c915d90..4ab5fe26abe56 100644 --- a/compiler/rustc_trait_selection/src/traits/query/outlives_bounds.rs +++ b/compiler/rustc_typeck/src/outlives/outlives_bounds.rs @@ -1,11 +1,11 @@ -use crate::infer::canonical::OriginalQueryValues; -use crate::infer::InferCtxt; -use crate::traits::query::NoSolution; -use crate::traits::{FulfillmentContext, ObligationCause, TraitEngine}; use rustc_hir as hir; use rustc_infer::traits::TraitEngineExt as _; use rustc_middle::ty::{self, Ty}; use rustc_span::source_map::Span; +use rustc_trait_selection::infer::canonical::OriginalQueryValues; +use rustc_trait_selection::infer::InferCtxt; +use rustc_trait_selection::traits::query::NoSolution; +use rustc_trait_selection::traits::{FulfillmentContext, ObligationCause, TraitEngine}; pub use rustc_middle::traits::query::OutlivesBound; From a51798a27ba215307dddd3ecc2bfc73f9f08efa9 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sat, 16 Oct 2021 01:38:49 +0900 Subject: [PATCH 10/11] Add some GATs related regression tests --- .../generic-associated-types/issue-88287.rs | 39 +++++++++++++++++++ .../generic-associated-types/issue-88405.rs | 16 ++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/test/ui/generic-associated-types/issue-88287.rs create mode 100644 src/test/ui/generic-associated-types/issue-88405.rs diff --git a/src/test/ui/generic-associated-types/issue-88287.rs b/src/test/ui/generic-associated-types/issue-88287.rs new file mode 100644 index 0000000000000..2e65af594a6bd --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-88287.rs @@ -0,0 +1,39 @@ +// check-pass +// edition:2018 + +#![feature(generic_associated_types)] +#![feature(type_alias_impl_trait)] + +use std::future::Future; + +trait SearchableResource { + type SearchResult; +} + +trait SearchableResourceExt: SearchableResource { + type Future<'f, A: 'f + ?Sized, B: 'f>: Future, ()>> + 'f + where + A: SearchableResource; + + fn search<'c>(&'c self, client: &'c ()) -> Self::Future<'c, Self, Criteria>; +} + +type SearchFutureTy<'f, A, B: 'f> +where + A: SearchableResource + ?Sized + 'f, += impl Future, ()>> + 'f; +impl SearchableResourceExt for T +where + T: SearchableResource, +{ + type Future<'f, A, B: 'f> + where + A: SearchableResource + ?Sized + 'f, + = SearchFutureTy<'f, A, B>; + + fn search<'c>(&'c self, _client: &'c ()) -> Self::Future<'c, Self, Criteria> { + async move { todo!() } + } +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-88405.rs b/src/test/ui/generic-associated-types/issue-88405.rs new file mode 100644 index 0000000000000..4a405bd3625c1 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-88405.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(generic_associated_types)] + +trait SomeTrait {} +trait OtherTrait { + type Item; +} + +trait ErrorSimpleExample { + type AssociatedType: SomeTrait; + type GatBounded; + type ErrorMinimal: OtherTrait>; +} + +fn main() {} From d3bddf3ea1b1717c8dc61056588162e4964ce3c9 Mon Sep 17 00:00:00 2001 From: Giles Cope Date: Fri, 15 Oct 2021 20:43:52 +0100 Subject: [PATCH 11/11] updating docs to reflect current situation --- library/core/src/sync/atomic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index b07752116e514..1247f33087558 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -62,7 +62,7 @@ //! some atomic operations. Maximally portable code will want to be careful //! about which atomic types are used. `AtomicUsize` and `AtomicIsize` are //! generally the most portable, but even then they're not available everywhere. -//! For reference, the `std` library requires pointer-sized atomics, although +//! For reference, the `std` library requires `AtomicBool`s and pointer-sized atomics, although //! `core` does not. //! //! Currently you'll need to use `#[cfg(target_arch)]` primarily to