diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 3856b7f4a4b82..a48e3e02bf9cb 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -89,12 +89,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { locations: Locations, category: ConstraintCategory, ) { - self.prove_predicates( - Some(ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate { + self.prove_predicate( + ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, constness: ty::BoundConstness::NotConst, polarity: ty::ImplPolarity::Positive, - }))), + })) + .to_predicate(self.tcx()), locations, category, ); diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index f8439d2e16355..cd31d60db8c4a 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -280,7 +280,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { // } // impl Foo for () { // type Bar = (); - // fn foo(&self) ->&() {} + // fn foo(&self) -> &() {} // } // ``` // Both &Self::Bar and &() are WF diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index e9fa33f656f31..48e7df131b563 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -90,7 +90,7 @@ macro_rules! span_mirbug_and_err { ($context:expr, $elem:expr, $($message:tt)*) => ({ { span_mirbug!($context, $elem, $($message)*); - $context.error() + $context.tcx().ty_error() } }) } @@ -181,107 +181,69 @@ pub(crate) fn type_check<'mir, 'tcx>( upvars, }; - let opaque_type_values = type_check_internal( + let mut checker = TypeChecker::new( infcx, - param_env, body, - promoted, + param_env, ®ion_bound_pairs, implicit_region_bound, &mut borrowck_context, - |mut cx| { - cx.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output); - liveness::generate( - &mut cx, - body, - elements, - flow_inits, - move_data, - location_table, - use_polonius, - ); - - translate_outlives_facts(&mut cx); - let opaque_type_values = - infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); - - opaque_type_values - .into_iter() - .map(|(opaque_type_key, decl)| { - cx.fully_perform_op( - Locations::All(body.span), - ConstraintCategory::OpaqueType, - CustomTypeOp::new( - |infcx| { - infcx.register_member_constraints( - param_env, - opaque_type_key, - decl.hidden_type.ty, - decl.hidden_type.span, - ); - Ok(InferOk { value: (), obligations: vec![] }) - }, - || "opaque_type_map".to_string(), - ), - ) - .unwrap(); - let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type); - trace!( - "finalized opaque type {:?} to {:#?}", - opaque_type_key, - hidden_type.ty.kind() - ); - if hidden_type.has_infer_types_or_consts() { - infcx.tcx.sess.delay_span_bug( - decl.hidden_type.span, - &format!("could not resolve {:#?}", hidden_type.ty.kind()), - ); - hidden_type.ty = infcx.tcx.ty_error(); - } - - (opaque_type_key, (hidden_type, decl.origin)) - }) - .collect() - }, ); - MirTypeckResults { constraints, universal_region_relations, opaque_type_values } -} + let mut verifier = TypeVerifier::new(&mut checker, promoted); + verifier.visit_body(&body); -#[instrument( - skip(infcx, body, promoted, region_bound_pairs, borrowck_context, extra), - level = "debug" -)] -fn type_check_internal<'a, 'tcx, R>( - infcx: &'a InferCtxt<'a, 'tcx>, - param_env: ty::ParamEnv<'tcx>, - body: &'a Body<'tcx>, - promoted: &'a IndexVec>, - region_bound_pairs: &'a RegionBoundPairs<'tcx>, - implicit_region_bound: ty::Region<'tcx>, - borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, - extra: impl FnOnce(TypeChecker<'a, 'tcx>) -> R, -) -> R { - let mut checker = TypeChecker::new( - infcx, + checker.typeck_mir(body); + + checker.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output); + liveness::generate( + &mut checker, body, - param_env, - region_bound_pairs, - implicit_region_bound, - borrowck_context, + elements, + flow_inits, + move_data, + location_table, + use_polonius, ); - let errors_reported = { - let mut verifier = TypeVerifier::new(&mut checker, promoted); - verifier.visit_body(&body); - verifier.errors_reported - }; - if !errors_reported { - // if verifier failed, don't do further checks to avoid ICEs - checker.typeck_mir(body); - } + translate_outlives_facts(&mut checker); + let opaque_type_values = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); + let opaque_type_values = opaque_type_values + .into_iter() + .map(|(opaque_type_key, decl)| { + checker + .fully_perform_op( + Locations::All(body.span), + ConstraintCategory::OpaqueType, + CustomTypeOp::new( + |infcx| { + infcx.register_member_constraints( + param_env, + opaque_type_key, + decl.hidden_type.ty, + decl.hidden_type.span, + ); + Ok(InferOk { value: (), obligations: vec![] }) + }, + || "opaque_type_map".to_string(), + ), + ) + .unwrap(); + let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type); + trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind()); + if hidden_type.has_infer_types_or_consts() { + infcx.tcx.sess.delay_span_bug( + decl.hidden_type.span, + &format!("could not resolve {:#?}", hidden_type.ty.kind()), + ); + hidden_type.ty = infcx.tcx.ty_error(); + } - extra(checker) + (opaque_type_key, (hidden_type, decl.origin)) + }) + .collect(); + + MirTypeckResults { constraints, universal_region_relations, opaque_type_values } } fn translate_outlives_facts(typeck: &mut TypeChecker<'_, '_>) { @@ -323,14 +285,11 @@ enum FieldAccessError { /// Verifies that MIR types are sane to not crash further checks. /// -/// The sanitize_XYZ methods here take an MIR object and compute its -/// type, calling `span_mirbug` and returning an error type if there -/// is a problem. +/// FIXME: Merge this with `TypeChecker`. struct TypeVerifier<'a, 'b, 'tcx> { cx: &'a mut TypeChecker<'b, 'tcx>, promoted: &'b IndexVec>, last_span: Span, - errors_reported: bool, } impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { @@ -387,34 +346,25 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { }; if let Some(uv) = maybe_uneval { if let Some(promoted) = uv.promoted { - let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>, - promoted: &Body<'tcx>, - ty, - san_ty| { - if let Err(terr) = verifier.cx.eq_types( + let promoted_body = &self.promoted[promoted]; + self.sanitize_promoted(promoted_body, location); + + let promoted_ty = promoted_body.return_ty(); + if let Err(terr) = self.cx.eq_types( + ty, + promoted_ty, + location.to_locations(), + ConstraintCategory::Boring, + ) { + span_mirbug!( + self, + promoted_body, + "bad promoted type ({:?}: {:?}): {:?}", ty, - san_ty, - location.to_locations(), - ConstraintCategory::Boring, - ) { - span_mirbug!( - verifier, - promoted, - "bad promoted type ({:?}: {:?}): {:?}", - ty, - san_ty, - terr - ); - }; + promoted_ty, + terr + ); }; - - if !self.errors_reported { - let promoted_body = &self.promoted[promoted]; - self.sanitize_promoted(promoted_body, location); - - let promoted_ty = promoted_body.return_ty(); - check_err(self, promoted_body, ty, promoted_ty); - } } else { if let Err(terr) = self.cx.fully_perform_op( location.to_locations(), @@ -450,14 +400,12 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { } } - if let ty::FnDef(def_id, substs) = *constant.literal.ty().kind() { - let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs); - self.cx.normalize_and_prove_instantiated_predicates( - def_id, - instantiated_predicates, - location.to_locations(), - ); - } + self.cx.prove_predicate( + ty::Binder::dummy(ty::PredicateKind::WellFormed(constant.literal.ty().into())) + .to_predicate(self.tcx()), + location.to_locations(), + ConstraintCategory::Boring, + ); } } @@ -512,9 +460,6 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { for local_decl in &body.local_decls { self.sanitize_type(local_decl, local_decl.ty); } - if self.errors_reported { - return; - } self.super_body(body); } } @@ -524,7 +469,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { cx: &'a mut TypeChecker<'b, 'tcx>, promoted: &'b IndexVec>, ) -> Self { - TypeVerifier { promoted, last_span: cx.body.span, cx, errors_reported: false } + TypeVerifier { promoted, last_span: cx.body.span, cx } } fn body(&self) -> &Body<'tcx> { @@ -558,13 +503,21 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { for elem in place.projection.iter() { if place_ty.variant_index.is_none() { if place_ty.ty.references_error() { - assert!(self.errors_reported); return PlaceTy::from_ty(self.tcx().ty_error()); } } place_ty = self.sanitize_projection(place_ty, elem, place, location); } + self.cx.prove_predicate( + ty::Binder::dummy(ty::PredicateKind::WellFormed( + self.body().local_decls[place.local].ty.into(), + )) + .to_predicate(self.tcx()), + location.to_locations(), + ConstraintCategory::Boring, + ); + if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { let tcx = self.tcx(); let trait_ref = ty::TraitRef { @@ -629,10 +582,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { self.visit_body(&promoted_body); - if !self.errors_reported { - // if verifier failed, don't do further checks to avoid ICEs - self.cx.typeck_mir(promoted_body); - } + self.cx.typeck_mir(promoted_body); self.cx.body = parent_body; // Merge the outlives constraints back in, at the given location. @@ -790,11 +740,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { } } - fn error(&mut self) -> Ty<'tcx> { - self.errors_reported = true; - self.tcx().ty_error() - } - fn field_ty( &mut self, parent: &dyn fmt::Debug, @@ -1926,7 +1871,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - &Rvalue::NullaryOp(_, ty) => { + &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => { let trait_ref = ty::TraitRef { def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), substs: tcx.mk_substs_trait(ty, &[]), diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 2b9cc75f1b753..f979d59059a52 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -113,7 +113,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( infcx.tcx.struct_span_lint_hir( lint::builtin::CONST_EVALUATABLE_UNCHECKED, infcx.tcx.hir().local_def_id_to_hir_id(local_def_id), - span, + tcx.def_span(local_def_id), |err| { err.build("cannot use constants which depend on generic parameters in types") .emit(); diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 6b63191eb583d..fec7d63058397 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -2878,8 +2878,8 @@ where #[stable(feature = "hash_extend_copy", since = "1.4.0")] impl<'a, K, V, S> Extend<(&'a K, &'a V)> for HashMap where - K: Eq + Hash + Copy, - V: Copy, + K: Eq + Hash + Copy + 'a, + V: Copy + 'a, S: BuildHasher, { #[inline] diff --git a/src/test/ui/borrowck/issue-7573.rs b/src/test/ui/borrowck/issue-7573.rs index 7c07411533ff0..f94cd75ab6e2e 100644 --- a/src/test/ui/borrowck/issue-7573.rs +++ b/src/test/ui/borrowck/issue-7573.rs @@ -17,6 +17,8 @@ pub fn remove_package_from_database() { lines_to_use.push(installed_id); //~^ ERROR borrowed data escapes outside of closure //~| NOTE `installed_id` escapes the closure body here + //~| NOTE requirement occurs because of a mutable reference to `Vec<&CrateId>` + //~| NOTE mutable references are invariant over their type parameter }; list_database(push_id); diff --git a/src/test/ui/borrowck/issue-7573.stderr b/src/test/ui/borrowck/issue-7573.stderr index 9d86286b8676c..69f198dc6aff8 100644 --- a/src/test/ui/borrowck/issue-7573.stderr +++ b/src/test/ui/borrowck/issue-7573.stderr @@ -9,6 +9,10 @@ LL | let push_id = |installed_id: &CrateId| { LL | LL | lines_to_use.push(installed_id); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `installed_id` escapes the closure body here + | + = note: requirement occurs because of a mutable reference to `Vec<&CrateId>` + = 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/const-generics/generic_const_exprs/function-call.rs b/src/test/ui/const-generics/generic_const_exprs/function-call.rs index b5de66621c50e..2405ede2dd967 100644 --- a/src/test/ui/const-generics/generic_const_exprs/function-call.rs +++ b/src/test/ui/const-generics/generic_const_exprs/function-call.rs @@ -1,3 +1,4 @@ +// compile-flags: -Zdeduplicate-diagnostics=yes // check-pass const fn foo() -> usize { diff --git a/src/test/ui/const-generics/generic_const_exprs/function-call.stderr b/src/test/ui/const-generics/generic_const_exprs/function-call.stderr index 0d8463714e8df..2cfc512400842 100644 --- a/src/test/ui/const-generics/generic_const_exprs/function-call.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/function-call.stderr @@ -1,5 +1,5 @@ warning: cannot use constants which depend on generic parameters in types - --> $DIR/function-call.rs:14:17 + --> $DIR/function-call.rs:15:17 | LL | let _ = [0; foo::()]; | ^^^^^^^^^^ diff --git a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs index 71d13ca61c9b3..4671e783f26b4 100644 --- a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs +++ b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs @@ -1,3 +1,4 @@ +// compile-flags: -Zdeduplicate-diagnostics=yes // check-pass #![allow(dead_code)] diff --git a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr index f9f6660f6b823..4d0cab012f99e 100644 --- a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr +++ b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr @@ -1,5 +1,5 @@ warning: cannot use constants which depend on generic parameters in types - --> $DIR/const-evaluatable-unchecked.rs:5:9 + --> $DIR/const-evaluatable-unchecked.rs:6:9 | LL | [0; std::mem::size_of::<*mut T>()]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | [0; std::mem::size_of::<*mut T>()]; = note: for more information, see issue #76200 warning: cannot use constants which depend on generic parameters in types - --> $DIR/const-evaluatable-unchecked.rs:16:21 + --> $DIR/const-evaluatable-unchecked.rs:17:21 | LL | let _ = [0; Self::ASSOC]; | ^^^^^^^^^^^ @@ -18,7 +18,7 @@ LL | let _ = [0; Self::ASSOC]; = note: for more information, see issue #76200 warning: cannot use constants which depend on generic parameters in types - --> $DIR/const-evaluatable-unchecked.rs:28:21 + --> $DIR/const-evaluatable-unchecked.rs:29:21 | LL | let _ = [0; Self::ASSOC]; | ^^^^^^^^^^^ diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr index e6ffe38ee92e8..c6f62a551b083 100644 --- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr @@ -1,5 +1,5 @@ error: implementation of `Parser` is not general enough - --> $DIR/issue-71955.rs:54:5 + --> $DIR/issue-71955.rs:52:5 | LL | foo(bar, "string", |s| s.len() == 5); | ^^^ implementation of `Parser` is not general enough @@ -8,7 +8,7 @@ LL | foo(bar, "string", |s| s.len() == 5); = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1` error: implementation of `Parser` is not general enough - --> $DIR/issue-71955.rs:58:5 + --> $DIR/issue-71955.rs:56:5 | LL | foo(baz, "string", |s| s.0.len() == 5); | ^^^ implementation of `Parser` is not general enough diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.nll.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.nll.stderr index 0f38f8e3283a2..cca402bbf5134 100644 --- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.nll.stderr +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.nll.stderr @@ -1,79 +1,38 @@ -error[E0308]: mismatched types - --> $DIR/issue-71955.rs:54:5 +error: implementation of `Parser` is not general enough + --> $DIR/issue-71955.rs:52:5 | LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Parser` is not general enough | - = note: expected type `for<'r, 's> FnOnce<(&'r &'s str,)>` - found type `for<'r> FnOnce<(&'r &str,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:54:24 - | -LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:34:9 - | -LL | F2: FnOnce(&::Output) -> bool - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`... + = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1` -error[E0308]: mismatched types - --> $DIR/issue-71955.rs:54:5 - | -LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `FnOnce<(&&str,)>` - found type `for<'r> FnOnce<(&'r &str,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:54:24 +error: implementation of `Parser` is not general enough + --> $DIR/issue-71955.rs:52:5 | LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:34:44 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Parser` is not general enough | -LL | F2: FnOnce(&::Output) -> bool - | ^^^^ + = note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`... + = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1` -error[E0308]: mismatched types - --> $DIR/issue-71955.rs:58:5 +error: implementation of `Parser` is not general enough + --> $DIR/issue-71955.rs:56:5 | LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Parser` is not general enough | - = note: expected type `for<'r, 's> FnOnce<(&'r Wrapper<'s>,)>` - found type `for<'r> FnOnce<(&'r Wrapper<'_>,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:58:24 - | -LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:34:9 - | -LL | F2: FnOnce(&::Output) -> bool - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`... + = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1` -error[E0308]: mismatched types - --> $DIR/issue-71955.rs:58:5 - | -LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `FnOnce<(&Wrapper<'_>,)>` - found type `for<'r> FnOnce<(&'r Wrapper<'_>,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:58:24 +error: implementation of `Parser` is not general enough + --> $DIR/issue-71955.rs:56:5 | LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:34:44 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Parser` is not general enough | -LL | F2: FnOnce(&::Output) -> bool - | ^^^^ + = note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`... + = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1` error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs index 4b7e207b96d49..e862d1cfa9d35 100644 --- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs @@ -6,8 +6,6 @@ // Since we are testing nll (and migration) explicitly as a separate // revisions, don't worry about the --compare-mode=nll on this test. -// ignore-compare-mode-nll - #![feature(rustc_attrs)] trait Parser<'s> { @@ -53,10 +51,10 @@ fn main() { foo(bar, "string", |s| s.len() == 5); //[migrate]~^ ERROR implementation of `Parser` is not general enough - //[nll]~^^ ERROR mismatched types - //[nll]~| ERROR mismatched types + //[nll]~^^ ERROR implementation of `Parser` is not general enough + //[nll]~| ERROR implementation of `Parser` is not general enough foo(baz, "string", |s| s.0.len() == 5); //[migrate]~^ ERROR implementation of `Parser` is not general enough - //[nll]~^^ ERROR mismatched types - //[nll]~| ERROR mismatched types + //[nll]~^^ ERROR implementation of `Parser` is not general enough + //[nll]~| ERROR implementation of `Parser` is not general enough } diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr index ff16bf0e078fc..6d64efd85e0c7 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr @@ -17,7 +17,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y); | - - ^^^^^^ assignment requires that `'1` must outlive `'2` | | | | | has type `&'1 i32` - | has type `&'_#2r mut &'2 i32` + | has type `&'2 mut &'_#3r i32` note: no external requirements --> $DIR/escape-argument-callee.rs:20:1 diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr index e1b446fc61f61..3bd31ce7c8f6c 100644 --- a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr +++ b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr @@ -10,6 +10,7 @@ LL | let mut closure1 = || p = &y; (&'_#1r mut &'_#2r i32, &'_#3r i32), ] = note: number of external vids: 4 + = note: where '_#3r: '_#1r = note: where '_#3r: '_#2r note: external requirements @@ -28,6 +29,7 @@ LL | | }; (&'_#1r mut &'_#2r i32, &'_#3r i32), ] = note: number of external vids: 4 + = note: where '_#3r: '_#1r = note: where '_#3r: '_#2r note: no external requirements diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr index 0ea1076c32ef4..06149c97437fe 100644 --- a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr +++ b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr @@ -10,6 +10,7 @@ LL | let mut closure = || p = &y; (&'_#1r mut &'_#2r i32, &'_#3r i32), ] = note: number of external vids: 4 + = note: where '_#3r: '_#1r = note: where '_#3r: '_#2r note: no external requirements diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr index 98c3c28fb43ff..b9987ea1943f2 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr @@ -18,6 +18,8 @@ LL | | }); = note: late-bound region is '_#4r = note: number of external vids: 5 = note: where '_#1r: '_#2r + = note: where '_#1r: '_#2r + = note: where '_#1r: '_#2r note: no external requirements --> $DIR/propagate-approximated-ref.rs:42:1 diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr index ec2c220b6b8a0..590e4027d0867 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr @@ -19,6 +19,7 @@ LL | | }); = note: late-bound region is '_#3r = note: number of external vids: 4 = note: where '_#1r: '_#0r + = note: where '_#1r: '_#0r note: no external requirements --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:31:1 diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr index 234212c88767a..5edfd0f0b4261 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr @@ -18,6 +18,9 @@ LL | | }); = note: late-bound region is '_#3r = note: late-bound region is '_#4r = note: number of external vids: 5 + = note: where '_#1r: '_#2r + = note: where '_#1r: '_#2r + = note: where '_#1r: '_#0r = note: where '_#1r: '_#0r note: no external requirements diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr index 8b9b043542057..903a8e61c5745 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr @@ -23,10 +23,14 @@ error: lifetime may not live long enough LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { | --------- - has type `&'_#7r Cell<&'1 u32>` | | - | has type `&'_#5r Cell<&'2 &'_#1r u32>` + | has type `&'2 Cell<&'_#6r &'_#1r u32>` LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` + | + = note: requirement occurs because of the type `Cell<&'_#38r u32>`, which makes the generic argument `&'_#38r u32` invariant + = note: the struct `Cell` is invariant over the parameter `T` + = help: see for more information about variance note: no external requirements --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:34:1 diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs index c1467fcc9b6cf..16028b6e984d7 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs @@ -40,6 +40,7 @@ fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { // Only works if 'x: 'y: demand_y(x, y, x.get()) //~^ ERROR + //~| ERROR }); } diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr index 060ce690f0306..f5951555abc21 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr @@ -1,4 +1,4 @@ -note: no external requirements +note: external requirements --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:39:47 | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { @@ -6,6 +6,7 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) LL | | +LL | | LL | | }); | |_____^ | @@ -16,17 +17,25 @@ LL | | }); ] = note: late-bound region is '_#3r = note: late-bound region is '_#4r + = note: number of external vids: 5 + = note: where '_#1r: '_#2r + = note: where '_#1r: '_#2r + = note: where '_#1r: '_#2r error: lifetime may not live long enough --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:41:9 | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - | ---------- ---------- has type `&'_#8r Cell<&'2 &'_#2r u32>` + | ---------- ---------- has type `&'2 Cell<&'_#9r &'_#2r u32>` | | | has type `&'_#6r Cell<&'1 &'_#1r u32>` LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` + | + = note: requirement occurs because of the type `Cell<&'_#44r u32>`, which makes the generic argument `&'_#44r u32` invariant + = note: the struct `Cell` is invariant over the parameter `T` + = help: see for more information about variance note: no external requirements --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:38:1 @@ -35,12 +44,25 @@ LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { LL | | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) -LL | | +... | LL | | }); LL | | } | |_^ | = note: defining type: supply -error: aborting due to previous error +error: lifetime may not live long enough + --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:41:9 + | +LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | demand_y(x, y, x.get()) + | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b` + | + = help: consider adding the following bound: `'a: 'b` + +error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/issue-95272.rs b/src/test/ui/nll/issue-95272.rs index 5b5308fb8c2ba..bcfbd7fb8b164 100644 --- a/src/test/ui/nll/issue-95272.rs +++ b/src/test/ui/nll/issue-95272.rs @@ -10,8 +10,7 @@ where fn test<'a, 'b>(x: Cell<&'a ()>, y: Cell<&'b ()>) { let f = check; - //~^ ERROR lifetime may not live long enough - f(x, y); + f(x, y); //~ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/nll/issue-95272.stderr b/src/test/ui/nll/issue-95272.stderr index 41346a4c699c1..711b441ee0289 100644 --- a/src/test/ui/nll/issue-95272.stderr +++ b/src/test/ui/nll/issue-95272.stderr @@ -1,16 +1,17 @@ error: lifetime may not live long enough - --> $DIR/issue-95272.rs:12:13 + --> $DIR/issue-95272.rs:13:5 | LL | fn test<'a, 'b>(x: Cell<&'a ()>, y: Cell<&'b ()>) { | -- -- lifetime `'b` defined here | | | lifetime `'a` defined here LL | let f = check; - | ^^^^^ assignment requires that `'a` must outlive `'b` +LL | f(x, y); + | ^^^^^^^ argument requires that `'a` must outlive `'b` | = help: consider adding the following bound: `'a: 'b` - = note: requirement occurs because of a function pointer to `check` - = note: the function `check` is invariant over the parameter `'a` + = note: requirement occurs because of the type `Cell<&()>`, which makes the generic argument `&()` invariant + = note: the struct `Cell` is invariant over the parameter `T` = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr index 4e0155bdf2cd0..4393f5d048b84 100644 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr @@ -168,7 +168,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); ] = note: late-bound region is '_#3r = note: number of external vids: 4 - = note: where >::AssocType: '_#2r + = note: where '_#1r: '_#2r note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:83:1 @@ -185,7 +185,7 @@ LL | | } = note: defining type: two_regions::<'_#1r, T> error: lifetime may not live long enough - --> $DIR/projection-two-region-trait-bound-closure.rs:87:29 + --> $DIR/projection-two-region-trait-bound-closure.rs:87:39 | LL | fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T) | -- -- lifetime `'b` defined here @@ -193,7 +193,7 @@ LL | fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T) | lifetime `'a` defined here ... LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ closure body requires that `'b` must outlive `'a` + | ^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` | = help: consider adding the following bound: `'b: 'a` @@ -209,7 +209,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); (), ] = note: number of external vids: 4 - = note: where >::AssocType: '_#3r + = note: where '_#2r: '_#3r note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:92:1 @@ -237,7 +237,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); (), ] = note: number of external vids: 3 - = note: where >::AssocType: '_#2r + = note: where '_#1r: '_#2r note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:101:1 diff --git a/src/test/ui/nll/type-check-pointer-coercions.stderr b/src/test/ui/nll/type-check-pointer-coercions.stderr index 24b07cabbac56..f54f1583d397f 100644 --- a/src/test/ui/nll/type-check-pointer-coercions.stderr +++ b/src/test/ui/nll/type-check-pointer-coercions.stderr @@ -22,21 +22,14 @@ LL | x | = help: consider adding the following bound: `'a: 'b` -error: lifetime may not live long enough +error[E0621]: explicit lifetime required in the type of `x` --> $DIR/type-check-pointer-coercions.rs:13:5 | LL | fn unique_to_mut<'a, 'b>(x: &mut &'a i32) -> *mut &'b i32 { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here + | ------------ help: add explicit lifetime `'b` to the type of `x`: `&'b mut &'a i32` LL | // Two errors because *mut is invariant LL | x - | ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` - | - = help: consider adding the following bound: `'b: 'a` - = note: requirement occurs because of a mutable pointer to `&i32` - = note: mutable pointers are invariant over their type parameter - = help: see for more information about variance + | ^ lifetime `'b` required error: lifetime may not live long enough --> $DIR/type-check-pointer-coercions.rs:13:5 @@ -54,8 +47,6 @@ LL | x = note: mutable pointers are invariant over their type parameter = help: see for more information about variance -help: `'b` and `'a` must be the same: replace one with the other - error: lifetime may not live long enough --> $DIR/type-check-pointer-coercions.rs:18:5 | @@ -109,3 +100,4 @@ LL | y error: aborting due to 8 previous errors +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/nll/type-check-pointer-comparisons.rs b/src/test/ui/nll/type-check-pointer-comparisons.rs index 3c900356fab3b..7d49f886fbe87 100644 --- a/src/test/ui/nll/type-check-pointer-comparisons.rs +++ b/src/test/ui/nll/type-check-pointer-comparisons.rs @@ -4,7 +4,7 @@ fn compare_const<'a, 'b>(x: *const &mut &'a i32, y: *const &mut &'b i32) { x == y; - //~^ ERROR lifetime may not live long enough + //~^ ERROR explicit lifetime required in the type of `y` //~| ERROR lifetime may not live long enough } diff --git a/src/test/ui/nll/type-check-pointer-comparisons.stderr b/src/test/ui/nll/type-check-pointer-comparisons.stderr index 8c88b2290395c..8d6aef147e0c0 100644 --- a/src/test/ui/nll/type-check-pointer-comparisons.stderr +++ b/src/test/ui/nll/type-check-pointer-comparisons.stderr @@ -1,17 +1,10 @@ -error: lifetime may not live long enough +error[E0621]: explicit lifetime required in the type of `y` --> $DIR/type-check-pointer-comparisons.rs:6:5 | LL | fn compare_const<'a, 'b>(x: *const &mut &'a i32, y: *const &mut &'b i32) { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here + | ------------------- help: add explicit lifetime `'a` to the type of `y`: `*const &'a mut &'b i32` LL | x == y; - | ^ requires that `'a` must outlive `'b` - | - = help: consider adding the following bound: `'a: 'b` - = note: requirement occurs because of a mutable reference to `&i32` - = note: mutable references are invariant over their type parameter - = help: see for more information about variance + | ^ lifetime `'a` required error: lifetime may not live long enough --> $DIR/type-check-pointer-comparisons.rs:6:10 @@ -28,8 +21,6 @@ LL | x == y; = note: mutable references are invariant over their type parameter = help: see for more information about variance -help: `'a` and `'b` must be the same: replace one with the other - error: lifetime may not live long enough --> $DIR/type-check-pointer-comparisons.rs:12:5 | @@ -96,3 +87,4 @@ help: `'a` and `'b` must be the same: replace one with the other error: aborting due to 6 previous errors +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.nll.stderr b/src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.nll.stderr index aeeee6e5003e8..3f4309f39744d 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.nll.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.nll.stderr @@ -4,9 +4,13 @@ error: lifetime may not live long enough LL | doit(0, &|x, y| { | - - has type `&'1 i32` | | - | has type `&Cell<&'2 i32>` + | has type `&'2 Cell<&i32>` LL | x.set(y); | ^^^^^^^^ argument requires that `'1` must outlive `'2` + | + = note: requirement occurs because of the type `Cell<&i32>`, which makes the generic argument `&i32` invariant + = note: the struct `Cell` is invariant over the parameter `T` + = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.nll.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.nll.stderr index 8e10242cb1331..fa9a3ce5e40ef 100644 --- a/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.nll.stderr +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.nll.stderr @@ -2,10 +2,14 @@ error: lifetime may not live long enough --> $DIR/underscore-lifetime-elison-mismatch.rs:5:42 | LL | fn foo(x: &mut Vec<&'_ u8>, y: &'_ u8) { x.push(y); } - | - - ^^^^^^^^^ argument requires that `'1` must outlive `'2` - | | | - | | let's call the lifetime of this reference `'1` - | let's call the lifetime of this reference `'2` + | - - ^^^^^^^^^ argument requires that `'1` must outlive `'2` + | | | + | | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` + | + = note: requirement occurs because of a mutable reference to `Vec<&u8>` + = note: mutable references are invariant over their type parameter + = help: see for more information about variance error: aborting due to previous error