diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 4260805f1dd1f..4b9bf52af8e7f 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -16,7 +16,7 @@ use rustc_hir::def::Res; use rustc_hir::definitions::DefPathData; use rustc_session::errors::report_lit_error; use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned}; -use rustc_span::symbol::{sym, Ident}; +use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::DUMMY_SP; use thin_vec::thin_vec; @@ -592,14 +592,38 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> hir::ExprKind<'hir> { let output = ret_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span))); - // Resume argument type: `ResumeTy` - let unstable_span = - self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone()); - let resume_ty = hir::QPath::LangItem(hir::LangItem::ResumeTy, unstable_span, None); + // Resume argument type, which should be `&mut Context<'_>`. + // NOTE: Using the `'static` lifetime here is technically cheating. + // The `Future::poll` argument really is `&'a mut Context<'b>`, but we cannot + // express the fact that we are not storing it across yield-points yet, + // and we would thus run into lifetime errors. + // See . + // Our lowering makes sure we are not mis-using the `_task_context` input type + // in the sense that we are indeed not using it across yield points. We + // get a fresh `&mut Context` for each resume / call of `Future::poll`. + // This "cheating" was previously done with a `ResumeTy` that contained a raw + // pointer, and a `get_context` accessor that pulled the `Context` lifetimes + // out of thin air. + let context_lifetime_ident = Ident::with_dummy_span(kw::StaticLifetime); + let context_lifetime = self.arena.alloc(hir::Lifetime { + hir_id: self.next_id(), + ident: context_lifetime_ident, + res: hir::LifetimeName::Static, + }); + let context_path = + hir::QPath::LangItem(hir::LangItem::Context, self.lower_span(span), None); + let context_ty = hir::MutTy { + ty: self.arena.alloc(hir::Ty { + hir_id: self.next_id(), + kind: hir::TyKind::Path(context_path), + span: self.lower_span(span), + }), + mutbl: hir::Mutability::Mut, + }; let input_ty = hir::Ty { hir_id: self.next_id(), - kind: hir::TyKind::Path(resume_ty), - span: unstable_span, + kind: hir::TyKind::Rptr(context_lifetime, context_ty), + span: self.lower_span(span), }; // The closure/generator `FnDecl` takes a single (resume) argument of type `input_ty`. @@ -710,7 +734,7 @@ impl<'hir> LoweringContext<'_, 'hir> { /// mut __awaitee => loop { /// match unsafe { ::std::future::Future::poll( /// <::std::pin::Pin>::new_unchecked(&mut __awaitee), - /// ::std::future::get_context(task_context), + /// task_context, /// ) } { /// ::std::task::Poll::Ready(result) => break result, /// ::std::task::Poll::Pending => {} @@ -751,7 +775,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // unsafe { // ::std::future::Future::poll( // ::std::pin::Pin::new_unchecked(&mut __awaitee), - // ::std::future::get_context(task_context), + // task_context, // ) // } let poll_expr = { @@ -769,16 +793,10 @@ impl<'hir> LoweringContext<'_, 'hir> { arena_vec![self; ref_mut_awaitee], Some(expr_hir_id), ); - let get_context = self.expr_call_lang_item_fn_mut( - gen_future_span, - hir::LangItem::GetContext, - arena_vec![self; task_context], - Some(expr_hir_id), - ); let call = self.expr_call_lang_item_fn( span, hir::LangItem::FuturePoll, - arena_vec![self; new_unchecked, get_context], + arena_vec![self; new_unchecked, task_context], Some(expr_hir_id), ); self.arena.alloc(self.expr_unsafe(call)) diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 04e68b9645525..3dfded2d930a0 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -240,7 +240,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> { let align = ImmTy::from_uint(target_align, args[1].layout).into(); let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty())?; - // We replace the entire entire function call with a "tail call". + // We replace the entire function call with a "tail call". // Note that this happens before the frame of the original function // is pushed on the stack. self.eval_fn_call( diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 79450fccfc4d8..e17d3e516a64f 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -676,6 +676,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return_to_block: StackPopCleanup, ) -> InterpResult<'tcx> { trace!("body: {:#?}", body); + // Clobber previous return place contents, nobody is supposed to be able to see them any more + // This also checks dereferenceable, but not align. We rely on all constructed places being + // sufficiently aligned (in particular we rely on `deref_operand` checking alignment). + self.write_uninit(return_place)?; // first push a stack frame so we have access to the local substs let pre_frame = Frame { body, diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 038509031b180..b51257df713ea 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -286,10 +286,9 @@ language_item_table! { // FIXME(swatinem): the following lang items are used for async lowering and // should become obsolete eventually. - ResumeTy, sym::ResumeTy, resume_ty, Target::Struct, GenericRequirement::None; IdentityFuture, sym::identity_future, identity_future_fn, Target::Fn, GenericRequirement::None; - GetContext, sym::get_context, get_context_fn, Target::Fn, GenericRequirement::None; + Context, sym::Context, context, Target::Struct, GenericRequirement::None; FuturePoll, sym::poll, future_poll_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; FromFrom, sym::from, from_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index f204d59d00556..66906b331da2e 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1930,6 +1930,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { adt_substs, ); let ty = tcx.bound_type_of(assoc_ty_did).subst(tcx, item_substs); + let ty = self.normalize_ty(span, ty); return Ok((ty, DefKind::AssocTy, assoc_ty_did)); } } diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 9db05eedbde79..8b2719c2f8aaa 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -7,7 +7,8 @@ use rustc_arena::DroplessArena; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, CrateVariancesMap, TyCtxt, TypeSuperVisitable, TypeVisitable}; +use rustc_middle::ty::{self, CrateVariancesMap, SubstsRef, Ty, TyCtxt}; +use rustc_middle::ty::{DefIdTree, TypeSuperVisitable, TypeVisitable}; use std::ops::ControlFlow; /// Defines the `TermsContext` basically houses an arena where we can @@ -75,11 +76,30 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc // type Foo<'a, 'b, 'c> = impl Trait<'a> + 'b; // ``` // we may not use `'c` in the hidden type. - struct OpaqueTypeLifetimeCollector { + struct OpaqueTypeLifetimeCollector<'tcx> { + tcx: TyCtxt<'tcx>, + root_def_id: DefId, variances: Vec, } - impl<'tcx> ty::TypeVisitor<'tcx> for OpaqueTypeLifetimeCollector { + impl<'tcx> OpaqueTypeLifetimeCollector<'tcx> { + #[instrument(level = "trace", skip(self), ret)] + fn visit_opaque(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) -> ControlFlow { + if def_id != self.root_def_id && self.tcx.is_descendant_of(def_id, self.root_def_id) { + let child_variances = self.tcx.variances_of(def_id); + for (a, v) in substs.iter().zip(child_variances) { + if *v != ty::Bivariant { + a.visit_with(self)?; + } + } + ControlFlow::CONTINUE + } else { + substs.visit_with(self) + } + } + } + + impl<'tcx> ty::TypeVisitor<'tcx> for OpaqueTypeLifetimeCollector<'tcx> { #[instrument(level = "trace", skip(self), ret)] fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { if let ty::RegionKind::ReEarlyBound(ebr) = r.kind() { @@ -87,6 +107,19 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc } r.super_visit_with(self) } + + #[instrument(level = "trace", skip(self), ret)] + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { + match t.kind() { + ty::Opaque(def_id, substs) => self.visit_opaque(*def_id, substs), + ty::Projection(proj) + if self.tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder => + { + self.visit_opaque(proj.item_def_id, proj.substs) + } + _ => t.super_visit_with(self), + } + } } // By default, RPIT are invariant wrt type and const generics, but they are bivariant wrt @@ -111,7 +144,8 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc } } - let mut collector = OpaqueTypeLifetimeCollector { variances }; + let mut collector = + OpaqueTypeLifetimeCollector { tcx, root_def_id: item_def_id.to_def_id(), variances }; let id_substs = ty::InternalSubsts::identity_for_item(tcx, item_def_id.to_def_id()); for pred in tcx.bound_explicit_item_bounds(item_def_id.to_def_id()).transpose_iter() { let pred = pred.map_bound(|(pred, _)| *pred).subst(tcx, id_substs); diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index cc69a1bb02db1..7df0114226418 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -406,7 +406,7 @@ impl Clone for StateData { /// The dataflow state for an instance of [`ValueAnalysis`]. /// /// Every instance specifies a lattice that represents the possible values of a single tracked -/// place. If we call this lattice `V` and set set of tracked places `P`, then a [`State`] is an +/// place. If we call this lattice `V` and set of tracked places `P`, then a [`State`] is an /// element of `{unreachable} ∪ (P -> V)`. This again forms a lattice, where the bottom element is /// `unreachable` and the top element is the mapping `p ↦ ⊤`. Note that the mapping `p ↦ ⊥` is not /// the bottom element (because joining an unreachable and any other reachable state yields a diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 51a53f7b37cc2..cf241b8922d61 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1927,7 +1927,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // We have a single lifetime => success. elision_lifetime = Elision::Param(res) } else { - // We have have multiple lifetimes => error. + // We have multiple lifetimes => error. elision_lifetime = Elision::Err; } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9e446c96db319..6125384549723 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -165,6 +165,7 @@ symbols! { Capture, Center, Clone, + Context, Continue, Copy, Count, @@ -264,7 +265,6 @@ symbols! { Relaxed, Release, Result, - ResumeTy, Return, Right, Rust, @@ -754,7 +754,6 @@ symbols! { generic_associated_types_extended, generic_const_exprs, generic_param_attrs, - get_context, global_allocator, global_asm, globs, diff --git a/library/core/src/future/mod.rs b/library/core/src/future/mod.rs index f2b961d62e00c..2a8e12fd4cf60 100644 --- a/library/core/src/future/mod.rs +++ b/library/core/src/future/mod.rs @@ -44,7 +44,7 @@ pub use poll_fn::{poll_fn, PollFn}; /// non-Send/Sync as well, and we don't want that. /// /// It also simplifies the HIR lowering of `.await`. -#[cfg_attr(not(bootstrap), lang = "ResumeTy")] +// FIXME(swatinem): This type can be removed when bumping the bootstrap compiler #[doc(hidden)] #[unstable(feature = "gen_future", issue = "50547")] #[derive(Debug, Copy, Clone)] @@ -61,6 +61,7 @@ unsafe impl Sync for ResumeTy {} /// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give /// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`). // This is `const` to avoid extra errors after we recover from `const async fn` +// FIXME(swatinem): This fn can be removed when bumping the bootstrap compiler #[cfg_attr(bootstrap, lang = "from_generator")] #[doc(hidden)] #[unstable(feature = "gen_future", issue = "50547")] @@ -102,7 +103,8 @@ where GenFuture(gen) } -#[lang = "get_context"] +// FIXME(swatinem): This fn can be removed when bumping the bootstrap compiler +#[cfg_attr(bootstrap, lang = "get_context")] #[doc(hidden)] #[unstable(feature = "gen_future", issue = "50547")] #[must_use] @@ -113,6 +115,10 @@ pub unsafe fn get_context<'a, 'b>(cx: ResumeTy) -> &'a mut Context<'b> { unsafe { &mut *cx.0.as_ptr().cast() } } +// FIXME(swatinem): This fn is currently needed to work around shortcomings +// in type and lifetime inference. +// See the comment at the bottom of `LoweringContext::make_async_expr` and +// . #[cfg_attr(not(bootstrap), lang = "identity_future")] #[doc(hidden)] #[unstable(feature = "gen_future", issue = "50547")] diff --git a/library/core/src/iter/sources/repeat_n.rs b/library/core/src/iter/sources/repeat_n.rs index dc69bf4df595e..fd8d25ce1a55e 100644 --- a/library/core/src/iter/sources/repeat_n.rs +++ b/library/core/src/iter/sources/repeat_n.rs @@ -20,7 +20,7 @@ use crate::mem::ManuallyDrop; /// #![feature(iter_repeat_n)] /// use std::iter; /// -/// // four of the the number four: +/// // four of the number four: /// let mut four_fours = iter::repeat_n(4, 4); /// /// assert_eq!(Some(4), four_fours.next()); diff --git a/library/core/src/str/pattern.rs b/library/core/src/str/pattern.rs index d76d6f8b2a2d9..19da6d2fbecbc 100644 --- a/library/core/src/str/pattern.rs +++ b/library/core/src/str/pattern.rs @@ -1894,7 +1894,7 @@ unsafe fn small_slice_eq(x: &[u8], y: &[u8]) -> bool { // Thus, derefencing both `px` and `py` in the loop below is safe. // // Moreover, we set `pxend` and `pyend` to be 4 bytes before the actual - // end of of `px` and `py`. Thus, the final dereference outside of the + // end of `px` and `py`. Thus, the final dereference outside of the // loop is guaranteed to be valid. (The final comparison will overlap with // the last comparison done in the loop for lengths that aren't multiples // of four.) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 0cff972df3a5a..9ab9b0ba1c797 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -174,6 +174,7 @@ impl RawWakerVTable { /// Currently, `Context` only serves to provide access to a [`&Waker`](Waker) /// which can be used to wake the current task. #[stable(feature = "futures_api", since = "1.36.0")] +#[cfg_attr(not(bootstrap), lang = "Context")] pub struct Context<'a> { waker: &'a Waker, // Ensure we future-proof against variance changes by forcing diff --git a/library/std/src/sync/mpmc/array.rs b/library/std/src/sync/mpmc/array.rs index 4db7b4990b97d..f71edc6c525a2 100644 --- a/library/std/src/sync/mpmc/array.rs +++ b/library/std/src/sync/mpmc/array.rs @@ -225,7 +225,7 @@ impl Channel { let slot = unsafe { self.buffer.get_unchecked(index) }; let stamp = slot.stamp.load(Ordering::Acquire); - // If the the stamp is ahead of the head by 1, we may attempt to pop. + // If the stamp is ahead of the head by 1, we may attempt to pop. if head + 1 == stamp { let new = if index + 1 < self.cap { // Same lap, incremented index. diff --git a/library/std/src/sync/mpsc/mod.rs b/library/std/src/sync/mpsc/mod.rs index 27fba761ada10..adb488d4378f0 100644 --- a/library/std/src/sync/mpsc/mod.rs +++ b/library/std/src/sync/mpsc/mod.rs @@ -629,9 +629,7 @@ impl Clone for Sender { #[stable(feature = "rust1", since = "1.0.0")] impl Drop for Sender { - fn drop(&mut self) { - let _ = self.inner; - } + fn drop(&mut self) {} } #[stable(feature = "mpsc_debug", since = "1.8.0")] @@ -751,9 +749,7 @@ impl Clone for SyncSender { #[stable(feature = "rust1", since = "1.0.0")] impl Drop for SyncSender { - fn drop(&mut self) { - let _ = self.inner; - } + fn drop(&mut self) {} } #[stable(feature = "mpsc_debug", since = "1.8.0")] @@ -1094,9 +1090,7 @@ impl IntoIterator for Receiver { #[stable(feature = "rust1", since = "1.0.0")] impl Drop for Receiver { - fn drop(&mut self) { - let _ = self.inner; - } + fn drop(&mut self) {} } #[stable(feature = "mpsc_debug", since = "1.8.0")] diff --git a/library/std/src/thread/scoped.rs b/library/std/src/thread/scoped.rs index e6dbf35bd0286..ada69aa8269f6 100644 --- a/library/std/src/thread/scoped.rs +++ b/library/std/src/thread/scoped.rs @@ -46,7 +46,7 @@ impl ScopeData { // We check for 'overflow' with usize::MAX / 2, to make sure there's no // chance it overflows to 0, which would result in unsoundness. if self.num_running_threads.fetch_add(1, Ordering::Relaxed) > usize::MAX / 2 { - // This can only reasonably happen by mem::forget()'ing many many ScopedJoinHandles. + // This can only reasonably happen by mem::forget()'ing a lot of ScopedJoinHandles. self.decrement_num_running_threads(false); panic!("too many running threads in thread scope"); } diff --git a/src/doc/book b/src/doc/book index 3f64052c048c6..a60f4316ec923 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 3f64052c048c6def93b94a2b514ee88bba918744 +Subproject commit a60f4316ec923a5ac2ed6a2eba6960edb832d855 diff --git a/src/doc/embedded-book b/src/doc/embedded-book index c533348edd69f..19f798d448835 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit c533348edd69f11a8f4225d633a05d7093fddbf3 +Subproject commit 19f798d448835a4888e3b3eae7fe69f1d61d8681 diff --git a/src/doc/nomicon b/src/doc/nomicon index 05532356e7a4d..ae406aa5287a9 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 05532356e7a4dbea2330aabb77611f5179493bb8 +Subproject commit ae406aa5287a9e025abb72343aaceec98458c117 diff --git a/src/doc/reference b/src/doc/reference index 9f0cc13ffcd27..3ae62681ff236 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 9f0cc13ffcd27c1fbe1ab766a9491e15ddcf4d19 +Subproject commit 3ae62681ff236d5528ef7c8c28ba7c6b2ecc6731 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 2b15c0abf2bad..a9869b4a3c4ca 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 2b15c0abf2bada6e00553814336bc3e2d8399097 +Subproject commit a9869b4a3c4cac3bc6099b41f088679e268400b8 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index d0dc6c97a6486..e269950a57fa6 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit d0dc6c97a6486f68bac782fff135086eae6d77ec +Subproject commit e269950a57fa6fcda356426545fb5aa3691a7ced diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index f44797fe55f17..c1c1241ba543c 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1660,8 +1660,6 @@ in storage.js /* Hide the sidebar offscreen while not in use. Doing this instead of display: none means the sidebar stays visible for screen readers, which is useful for navigation. */ left: -1000px; - margin: 0; - padding: 0; z-index: 11; /* Reduce height slightly to account for mobile topbar. */ height: calc(100vh - 45px); diff --git a/src/test/rustdoc-gui/method-margins.goml b/src/test/rustdoc-gui/method-margins.goml index 397bcd40b36c4..ed36bcdec17d2 100644 --- a/src/test/rustdoc-gui/method-margins.goml +++ b/src/test/rustdoc-gui/method-margins.goml @@ -1,3 +1,4 @@ +// This test ensures that the margins on methods are coherent inside an impl block. goto: "file://" + |DOC_PATH| + "/test_docs/trait_members/struct.HasTrait.html#impl-TraitMembers-for-HasTrait" assert-count: ("#trait-implementations-list > .rustdoc-toggle", 1) diff --git a/src/test/ui/associated-inherent-types/normalize-projection-0.rs b/src/test/ui/associated-inherent-types/normalize-projection-0.rs new file mode 100644 index 0000000000000..50763ecddf99c --- /dev/null +++ b/src/test/ui/associated-inherent-types/normalize-projection-0.rs @@ -0,0 +1,22 @@ +// check-pass + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct S(T); + +impl S { + type P = ::P; +} + +trait O { + type P; +} + +impl O for i32 { + type P = String; +} + +fn main() { + let _: S::P = String::new(); +} diff --git a/src/test/ui/associated-inherent-types/normalize-projection-1.rs b/src/test/ui/associated-inherent-types/normalize-projection-1.rs new file mode 100644 index 0000000000000..2f7b2551a03ec --- /dev/null +++ b/src/test/ui/associated-inherent-types/normalize-projection-1.rs @@ -0,0 +1,22 @@ +// check-pass + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct S; + +impl S { + type P = ::P; +} + +trait O { + type P; +} + +impl O for i32 { + type P = String; +} + +fn main() { + let _: S::P = String::new(); +} diff --git a/src/test/ui/async-await/async-await-let-else.drop-tracking.stderr b/src/test/ui/async-await/async-await-let-else.drop-tracking.stderr index 3be7f370da3f5..616623ee07759 100644 --- a/src/test/ui/async-await/async-await-let-else.drop-tracking.stderr +++ b/src/test/ui/async-await/async-await-let-else.drop-tracking.stderr @@ -40,7 +40,7 @@ LL | async fn bar2(_: T) -> ! { LL | | panic!() LL | | } | |_^ - = note: required because it captures the following types: `ResumeTy`, `Option`, `impl Future`, `()` + = note: required because it captures the following types: `&mut Context<'_>`, `Option`, `impl Future`, `()` note: required because it's used within this `async fn` body --> $DIR/async-await-let-else.rs:21:32 | diff --git a/src/test/ui/async-await/issue-68112.drop_tracking.stderr b/src/test/ui/async-await/issue-68112.drop_tracking.stderr index f2802698fd5b6..1c90bedae790c 100644 --- a/src/test/ui/async-await/issue-68112.drop_tracking.stderr +++ b/src/test/ui/async-await/issue-68112.drop_tracking.stderr @@ -57,7 +57,7 @@ note: required because it appears within the type `impl Future impl Future>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: required because it captures the following types: `ResumeTy`, `impl Future>>`, `()`, `Ready` + = note: required because it captures the following types: `&mut Context<'_>`, `impl Future>>`, `()`, `Ready` note: required because it's used within this `async` block --> $DIR/issue-68112.rs:60:20 | diff --git a/src/test/ui/async-await/issue-68112.no_drop_tracking.stderr b/src/test/ui/async-await/issue-68112.no_drop_tracking.stderr index 38eb85b302fd5..e09ae7fedd805 100644 --- a/src/test/ui/async-await/issue-68112.no_drop_tracking.stderr +++ b/src/test/ui/async-await/issue-68112.no_drop_tracking.stderr @@ -57,7 +57,7 @@ note: required because it appears within the type `impl Future impl Future>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: required because it captures the following types: `ResumeTy`, `impl Future>>`, `()`, `i32`, `Ready` + = note: required because it captures the following types: `&mut Context<'_>`, `impl Future>>`, `()`, `i32`, `Ready` note: required because it's used within this `async` block --> $DIR/issue-68112.rs:60:20 | diff --git a/src/test/ui/async-await/issue-69446-fnmut-capture.stderr b/src/test/ui/async-await/issue-69446-fnmut-capture.stderr index 3d2b0402bc52c..e6ad2f0d444bb 100644 --- a/src/test/ui/async-await/issue-69446-fnmut-capture.stderr +++ b/src/test/ui/async-await/issue-69446-fnmut-capture.stderr @@ -14,6 +14,9 @@ LL | | }); | = note: `FnMut` closures only have access to their captured variables while they are executing... = note: ...therefore, they cannot allow references to captured variables to escape + = note: requirement occurs because of a mutable reference to `Context<'_>` + = note: mutable references are invariant over their type parameter + = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr index 721234aa4a782..a8fd97cde8f7a 100644 --- a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr +++ b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr @@ -18,7 +18,7 @@ LL | async fn baz(_c: impl FnMut() -> T) where T: Future { | ___________________________________________________________________^ LL | | } | |_^ - = note: required because it captures the following types: `ResumeTy`, `impl Future`, `()` + = note: required because it captures the following types: `&mut Context<'_>`, `impl Future`, `()` note: required because it's used within this `async` block --> $DIR/issue-70935-complex-spans.rs:16:5 | diff --git a/src/test/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr b/src/test/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr index 17b4ef7bdc671..25876d5084015 100644 --- a/src/test/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr +++ b/src/test/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr @@ -11,7 +11,7 @@ LL | async fn foo() { | = help: within `impl Future`, the trait `Send` is not implemented for `NotSend` = note: required because it appears within the type `(NotSend,)` - = note: required because it captures the following types: `ResumeTy`, `(NotSend,)`, `()`, `impl Future` + = note: required because it captures the following types: `&mut Context<'_>`, `(NotSend,)`, `()`, `impl Future` note: required because it's used within this `async fn` body --> $DIR/partial-drop-partial-reinit.rs:31:16 | diff --git a/src/test/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr b/src/test/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr index 34d8a159f1064..dba2a620779f0 100644 --- a/src/test/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr +++ b/src/test/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr @@ -11,7 +11,7 @@ LL | async fn foo() { | = help: within `impl Future`, the trait `Send` is not implemented for `NotSend` = note: required because it appears within the type `(NotSend,)` - = note: required because it captures the following types: `ResumeTy`, `(NotSend,)`, `impl Future`, `()` + = note: required because it captures the following types: `&mut Context<'_>`, `(NotSend,)`, `impl Future`, `()` note: required because it's used within this `async fn` body --> $DIR/partial-drop-partial-reinit.rs:31:16 | diff --git a/src/test/ui/impl-trait/nested-return-type4.rs b/src/test/ui/impl-trait/nested-return-type4.rs new file mode 100644 index 0000000000000..cec70bb1a0d9e --- /dev/null +++ b/src/test/ui/impl-trait/nested-return-type4.rs @@ -0,0 +1,8 @@ +// edition: 2021 + +fn test<'s: 's>(s: &'s str) -> impl std::future::Future { + async move { let _s = s; } + //~^ ERROR hidden type for `impl Future` captures lifetime that does not appear in bounds +} + +fn main() {} diff --git a/src/test/ui/impl-trait/nested-return-type4.stderr b/src/test/ui/impl-trait/nested-return-type4.stderr new file mode 100644 index 0000000000000..e761a60e79c27 --- /dev/null +++ b/src/test/ui/impl-trait/nested-return-type4.stderr @@ -0,0 +1,20 @@ +error[E0700]: hidden type for `impl Future` captures lifetime that does not appear in bounds + --> $DIR/nested-return-type4.rs:4:5 + | +LL | fn test<'s: 's>(s: &'s str) -> impl std::future::Future { + | -- hidden type `[async block@$DIR/nested-return-type4.rs:4:5: 4:31]` captures the lifetime `'s` as defined here +LL | async move { let _s = s; } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: to declare that `impl Future` captures `'s`, you can add an explicit `'s` lifetime bound + | +LL | fn test<'s: 's>(s: &'s str) -> impl std::future::Future + 's { + | ++++ +help: to declare that `impl Sized` captures `'s`, you can add an explicit `'s` lifetime bound + | +LL | fn test<'s: 's>(s: &'s str) -> impl std::future::Future { + | ++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/regions/closure-in-projection-issue-97405.rs b/src/test/ui/regions/closure-in-projection-issue-97405.rs index e567d5c2723f2..88b1c1396516d 100644 --- a/src/test/ui/regions/closure-in-projection-issue-97405.rs +++ b/src/test/ui/regions/closure-in-projection-issue-97405.rs @@ -22,11 +22,11 @@ fn good_generic_fn() { // This should fail because `T` ends up in the upvars of the closure. fn bad_generic_fn(t: T) { assert_static(opaque(async move { t; }).next()); - //~^ ERROR the associated type `::Item` may not live long enough + //~^ ERROR the parameter type `T` may not live long enough assert_static(opaque(move || { t; }).next()); //~^ ERROR the associated type `::Item` may not live long enough assert_static(opaque(opaque(async move { t; }).next()).next()); - //~^ ERROR the associated type `::Item` may not live long enough + //~^ ERROR the parameter type `T` may not live long enough } fn main() {} diff --git a/src/test/ui/regions/closure-in-projection-issue-97405.stderr b/src/test/ui/regions/closure-in-projection-issue-97405.stderr index c08f1059ebf58..907964aaf379e 100644 --- a/src/test/ui/regions/closure-in-projection-issue-97405.stderr +++ b/src/test/ui/regions/closure-in-projection-issue-97405.stderr @@ -1,11 +1,13 @@ -error[E0310]: the associated type `::Item` may not live long enough +error[E0310]: the parameter type `T` may not live long enough --> $DIR/closure-in-projection-issue-97405.rs:24:5 | LL | assert_static(opaque(async move { t; }).next()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `::Item: 'static`... - = note: ...so that the type `::Item` will meet its required lifetime bounds +help: consider adding an explicit lifetime bound... + | +LL | fn bad_generic_fn(t: T) { + | +++++++++ error[E0310]: the associated type `::Item` may not live long enough --> $DIR/closure-in-projection-issue-97405.rs:26:5 @@ -16,14 +18,16 @@ LL | assert_static(opaque(move || { t; }).next()); = help: consider adding an explicit lifetime bound `::Item: 'static`... = note: ...so that the type `::Item` will meet its required lifetime bounds -error[E0310]: the associated type `::Item` may not live long enough +error[E0310]: the parameter type `T` may not live long enough --> $DIR/closure-in-projection-issue-97405.rs:28:5 | LL | assert_static(opaque(opaque(async move { t; }).next()).next()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `::Item: 'static`... - = note: ...so that the type `::Item` will meet its required lifetime bounds +help: consider adding an explicit lifetime bound... + | +LL | fn bad_generic_fn(t: T) { + | +++++++++ error: aborting due to 3 previous errors diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs b/src/test/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs index 6b7d94603b567..a8deb8a7550bc 100644 --- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs +++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs @@ -5,7 +5,7 @@ struct Foo { impl PartialEq for Foo { fn eq(&self, _: &Foo) -> bool { - false // ha ha sucker! + false // ha ha! } } diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 0d9a629e179b8..64d97e9144230 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -260,9 +260,9 @@ impl TestProps { props.load_from(testfile, cfg, config); match (props.pass_mode, props.fail_mode) { - (None, None) => props.fail_mode = Some(FailMode::Check), - (Some(_), None) | (None, Some(_)) => {} + (None, None) if config.mode == Mode::Ui => props.fail_mode = Some(FailMode::Check), (Some(_), Some(_)) => panic!("cannot use a *-fail and *-pass mode together"), + _ => {} } props @@ -522,8 +522,8 @@ impl TestProps { } pub fn pass_mode(&self, config: &Config) -> Option { - if !self.ignore_pass && self.fail_mode.is_none() && config.mode == Mode::Ui { - if let (mode @ Some(_), Some(_)) = (config.force_pass_mode, self.pass_mode) { + if !self.ignore_pass && self.fail_mode.is_none() { + if let mode @ Some(_) = config.force_pass_mode { return mode; } }