diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 02caae7a90a91..11c893a7cb6d9 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1442,6 +1442,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// the message in `secondary_span` as the primary label, and apply the message that would /// otherwise be used for the primary label on the `secondary_span` `Span`. This applies on /// E0271, like `src/test/ui/issues/issue-39970.stderr`. + #[tracing::instrument( + level = "debug", + skip(self, diag, secondary_span, swap_secondary_and_primary, force_label) + )] pub fn note_type_err( &self, diag: &mut Diagnostic, @@ -1453,7 +1457,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { force_label: bool, ) { let span = cause.span(self.tcx); - debug!("note_type_err cause={:?} values={:?}, terr={:?}", cause, values, terr); // For some types of errors, expected-found does not make // sense, so just ignore the values we were given. @@ -1621,9 +1624,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } }; - // Ignore msg for object safe coercion - // since E0038 message will be printed match terr { + // Ignore msg for object safe coercion + // since E0038 message will be printed TypeError::ObjectUnsafeCoercion(_) => {} _ => { let mut label_or_note = |span: Span, msg: &str| { @@ -1774,6 +1777,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // It reads better to have the error origin as the final // thing. self.note_error_origin(diag, cause, exp_found, terr); + + debug!(?diag); } fn suggest_tuple_pattern( diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index a0fe632f11a07..a6c14ea0de343 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -135,11 +135,10 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { ArgCount => write!(f, "incorrect number of function parameters"), FieldMisMatch(adt, field) => write!(f, "field type mismatch: {}.{}", adt, field), RegionsDoesNotOutlive(..) => write!(f, "lifetime mismatch"), - RegionsInsufficientlyPolymorphic(br, _) => write!( - f, - "expected bound lifetime parameter{}, found concrete lifetime", - br_string(br) - ), + // Actually naming the region here is a bit confusing because context is lacking + RegionsInsufficientlyPolymorphic(..) => { + write!(f, "one type is more general than the other") + } RegionsOverlyPolymorphic(br, _) => write!( f, "expected concrete lifetime, found bound lifetime parameter{}", diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 56acf65d9c5aa..9df86c6ada134 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -151,6 +151,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// /// * From each pre-binding block to the next pre-binding block. /// * From each otherwise block to the next pre-binding block. + #[tracing::instrument(level = "debug", skip(self, arms))] pub(crate) fn match_expr( &mut self, destination: Place<'tcx>, diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs index d0b18ce67c6d8..59750d5d0b88e 100644 --- a/compiler/rustc_mir_build/src/thir/cx/block.rs +++ b/compiler/rustc_mir_build/src/thir/cx/block.rs @@ -75,6 +75,7 @@ impl<'tcx> Cx<'tcx> { }; let mut pattern = self.pattern_from_hir(local.pat); + debug!(?pattern); if let Some(ty) = &local.ty { if let Some(&user_ty) = diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 13b4e90ca09ce..bd17df60cd788 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -98,6 +98,7 @@ impl<'tcx> Cx<'tcx> { } } + #[tracing::instrument(level = "debug", skip(self))] pub(crate) fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Pat<'tcx> { let p = match self.tcx.hir().get(p.hir_id) { Node::Pat(p) | Node::Binding(p) => p, diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index 9aff854c80305..3632e14385fe9 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -56,6 +56,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut all_arms_diverge = Diverges::WarnedAlways; let expected = orig_expected.adjust_for_branches(self); + debug!(?expected); let mut coercion = { let coerce_first = match expected { @@ -127,6 +128,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(&arm.body), arm_ty, Some(&mut |err: &mut Diagnostic| { + let Some(ret) = self.ret_type_span else { + return; + }; + let Expectation::IsLast(stmt) = orig_expected else { + return + }; let can_coerce_to_return_ty = match self.ret_coercion.as_ref() { Some(ret_coercion) if self.in_tail_expr => { let ret_ty = ret_coercion.borrow().expected_ty(); @@ -138,38 +145,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => false, }; - if let (Expectation::IsLast(stmt), Some(ret), true) = - (orig_expected, self.ret_type_span, can_coerce_to_return_ty) - { - let semi_span = expr.span.shrink_to_hi().with_hi(stmt.hi()); - let mut ret_span: MultiSpan = semi_span.into(); - ret_span.push_span_label( - expr.span, - "this could be implicitly returned but it is a statement, not a \ - tail expression" - .to_owned(), - ); - ret_span.push_span_label( - ret, - "the `match` arms can conform to this return type".to_owned(), - ); - ret_span.push_span_label( - semi_span, - "the `match` is a statement because of this semicolon, consider \ - removing it" - .to_owned(), - ); - err.span_note( - ret_span, - "you might have meant to return the `match` expression", - ); - err.tool_only_span_suggestion( - semi_span, - "remove this semicolon", - String::new(), - Applicability::MaybeIncorrect, - ); + if !can_coerce_to_return_ty { + return; } + + let semi_span = expr.span.shrink_to_hi().with_hi(stmt.hi()); + let mut ret_span: MultiSpan = semi_span.into(); + ret_span.push_span_label( + expr.span, + "this could be implicitly returned but it is a statement, not a \ + tail expression" + .to_owned(), + ); + ret_span.push_span_label( + ret, + "the `match` arms can conform to this return type".to_owned(), + ); + ret_span.push_span_label( + semi_span, + "the `match` is a statement because of this semicolon, consider \ + removing it" + .to_owned(), + ); + err.span_note( + ret_span, + "you might have meant to return the `match` expression", + ); + err.tool_only_span_suggestion( + semi_span, + "remove this semicolon", + String::new(), + Applicability::MaybeIncorrect, + ); }), false, ); @@ -199,7 +206,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We won't diverge unless the scrutinee or all arms diverge. self.diverges.set(scrut_diverges | all_arms_diverge); - coercion.complete(self) + let match_ty = coercion.complete(self); + debug!(?match_ty); + match_ty } fn get_appropriate_arm_semicolon_removal_span( diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index a17b13d49fd7f..6d540bf7e4f4b 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -737,14 +737,27 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { F: FnOnce(Ty<'tcx>) -> Vec>, G: FnOnce(Ty<'tcx>) -> Vec>, { - if let ty::FnPtr(fn_ty_b) = b.kind() - && let (hir::Unsafety::Normal, hir::Unsafety::Unsafe) = - (fn_ty_a.unsafety(), fn_ty_b.unsafety()) - { - let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a); - return self.unify_and(unsafe_a, b, to_unsafe); - } - self.unify_and(a, b, normal) + self.commit_unconditionally(|snapshot| { + let result = if let ty::FnPtr(fn_ty_b) = b.kind() + && let (hir::Unsafety::Normal, hir::Unsafety::Unsafe) = + (fn_ty_a.unsafety(), fn_ty_b.unsafety()) + { + let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a); + self.unify_and(unsafe_a, b, to_unsafe) + } else { + self.unify_and(a, b, normal) + }; + + // FIXME(#73154): This is a hack. Currently LUB can generate + // unsolvable constraints. Additionally, it returns `a` + // unconditionally, even when the "LUB" is `b`. In the future, we + // want the coerced type to be the actual supertype of these two, + // but for now, we want to just error to ensure we don't lock + // ourselves into a specific behavior with NLL. + self.leak_check(false, snapshot)?; + + result + }) } fn coerce_from_fn_pointer( @@ -1133,8 +1146,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (adjustments, target) = self.register_infer_ok_obligations(ok); self.apply_adjustments(new, adjustments); debug!( - "coercion::try_find_coercion_lub: was able to coerce from previous type {:?} to new type {:?}", - prev_ty, new_ty, + "coercion::try_find_coercion_lub: was able to coerce from new type {:?} to previous type {:?} ({:?})", + new_ty, prev_ty, target ); return Ok(target); } @@ -1190,15 +1203,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } Ok(ok) => { - debug!( - "coercion::try_find_coercion_lub: was able to coerce previous type {:?} to new type {:?}", - prev_ty, new_ty, - ); let (adjustments, target) = self.register_infer_ok_obligations(ok); for expr in exprs { let expr = expr.as_coercion_site(); self.apply_adjustments(expr, adjustments.clone()); } + debug!( + "coercion::try_find_coercion_lub: was able to coerce previous type {:?} to new type {:?} ({:?})", + prev_ty, new_ty, target + ); Ok(target) } } @@ -1430,6 +1443,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { }) }; + debug!(?result); match result { Ok(v) => { self.final_ty = Some(v); @@ -1520,7 +1534,10 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { augment_error(&mut err); } - if let Some(expr) = expression { + let is_insufficiently_polymorphic = + matches!(coercion_error, TypeError::RegionsInsufficientlyPolymorphic(..)); + + if !is_insufficiently_polymorphic && let Some(expr) = expression { fcx.emit_coerce_suggestions( &mut err, expr, diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs index ceb57386e300f..d0d2841209a6e 100644 --- a/compiler/rustc_typeck/src/check/demand.rs +++ b/compiler/rustc_typeck/src/check/demand.rs @@ -129,6 +129,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// /// N.B., this code relies on `self.diverges` to be accurate. In particular, assignments to `!` /// will be permitted if the diverges flag is currently "always". + #[tracing::instrument(level = "debug", skip(self, expr, expected_ty_expr, allow_two_phase))] pub fn demand_coerce_diag( &self, expr: &hir::Expr<'tcx>, @@ -150,7 +151,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expr_ty = self.resolve_vars_with_obligations(checked_ty); let mut err = self.report_mismatched_types(&cause, expected, expr_ty, e.clone()); - self.emit_coerce_suggestions(&mut err, expr, expr_ty, expected, expected_ty_expr, Some(e)); + let is_insufficiently_polymorphic = + matches!(e, TypeError::RegionsInsufficientlyPolymorphic(..)); + + // FIXME(#73154): For now, we do leak check when coercing function + // pointers in typeck, instead of only during borrowck. This can lead + // to these `RegionsInsufficientlyPolymorphic` errors that aren't helpful. + if !is_insufficiently_polymorphic { + self.emit_coerce_suggestions( + &mut err, + expr, + expr_ty, + expected, + expected_ty_expr, + Some(e), + ); + } (expected, Some(err)) } diff --git a/src/test/ui/hr-subtype/placeholder-pattern-fail.nll.stderr b/src/test/ui/hr-subtype/placeholder-pattern-fail.nll.stderr index 1836249efdb2a..73b0a31736447 100644 --- a/src/test/ui/hr-subtype/placeholder-pattern-fail.nll.stderr +++ b/src/test/ui/hr-subtype/placeholder-pattern-fail.nll.stderr @@ -1,37 +1,12 @@ error[E0308]: mismatched types - --> $DIR/placeholder-pattern-fail.rs:9:12 + --> $DIR/placeholder-pattern-fail.rs:9:47 | LL | let _: for<'a, 'b> fn(Inv<'a>, Inv<'b>) = sub; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^ one type is more general than the other | = note: expected fn pointer `for<'a, 'b> fn(Inv<'a>, Inv<'b>)` found fn pointer `for<'a> fn(Inv<'a>, Inv<'a>)` -error[E0308]: mismatched types - --> $DIR/placeholder-pattern-fail.rs:9:12 - | -LL | let _: for<'a, 'b> fn(Inv<'a>, Inv<'b>) = sub; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected fn pointer `for<'a, 'b> fn(Inv<'a>, Inv<'b>)` - found fn pointer `for<'a> fn(Inv<'a>, Inv<'a>)` - -error: lifetime may not live long enough - --> $DIR/placeholder-pattern-fail.rs:14:13 - | -LL | fn simple1<'c>(x: (&'c i32,)) { - | -- lifetime `'c` defined here -LL | let _x: (&'static i32,) = x; - | ^^^^^^^^^^^^^^^ type annotation requires that `'c` must outlive `'static` - -error: lifetime may not live long enough - --> $DIR/placeholder-pattern-fail.rs:19:12 - | -LL | fn simple2<'c>(x: (&'c i32,)) { - | -- lifetime `'c` defined here -LL | let _: (&'static i32,) = x; - | ^^^^^^^^^^^^^^^ type annotation requires that `'c` must outlive `'static` - -error: aborting due to 4 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/hrtb/hrtb-exists-forall-fn.nll.stderr b/src/test/ui/hrtb/hrtb-exists-forall-fn.nll.stderr index 1ee3c67496397..9914783d9767d 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-fn.nll.stderr +++ b/src/test/ui/hrtb/hrtb-exists-forall-fn.nll.stderr @@ -1,8 +1,8 @@ error[E0308]: mismatched types - --> $DIR/hrtb-exists-forall-fn.rs:17:12 + --> $DIR/hrtb-exists-forall-fn.rs:17:34 | LL | let _: for<'b> fn(&'b u32) = foo(); - | ^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^ one type is more general than the other | = note: expected fn pointer `for<'b> fn(&'b u32)` found fn pointer `fn(&u32)` diff --git a/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.stderr b/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.baseleak.stderr similarity index 90% rename from src/test/ui/lub-glb/old-lub-glb-hr-noteq1.stderr rename to src/test/ui/lub-glb/old-lub-glb-hr-noteq1.baseleak.stderr index 305e952d6046b..4448f9326cb94 100644 --- a/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.stderr +++ b/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.baseleak.stderr @@ -1,5 +1,5 @@ error[E0308]: `match` arms have incompatible types - --> $DIR/old-lub-glb-hr-noteq1.rs:11:14 + --> $DIR/old-lub-glb-hr-noteq1.rs:17:14 | LL | let z = match 22 { | _____________- @@ -7,6 +7,9 @@ LL | | 0 => x, | | - this is found to be of type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` LL | | _ => y, | | ^ one type is more general than the other +LL | | +... | +LL | | LL | | }; | |_____- `match` arms have incompatible types | diff --git a/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.basenoleak.stderr b/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.basenoleak.stderr new file mode 100644 index 0000000000000..4448f9326cb94 --- /dev/null +++ b/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.basenoleak.stderr @@ -0,0 +1,21 @@ +error[E0308]: `match` arms have incompatible types + --> $DIR/old-lub-glb-hr-noteq1.rs:17:14 + | +LL | let z = match 22 { + | _____________- +LL | | 0 => x, + | | - this is found to be of type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` +LL | | _ => y, + | | ^ one type is more general than the other +LL | | +... | +LL | | +LL | | }; + | |_____- `match` arms have incompatible types + | + = note: expected fn pointer `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` + found fn pointer `for<'a> fn(&'a u8, &'a u8) -> &'a u8` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllleak.stderr b/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllleak.stderr new file mode 100644 index 0000000000000..4448f9326cb94 --- /dev/null +++ b/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllleak.stderr @@ -0,0 +1,21 @@ +error[E0308]: `match` arms have incompatible types + --> $DIR/old-lub-glb-hr-noteq1.rs:17:14 + | +LL | let z = match 22 { + | _____________- +LL | | 0 => x, + | | - this is found to be of type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` +LL | | _ => y, + | | ^ one type is more general than the other +LL | | +... | +LL | | +LL | | }; + | |_____- `match` arms have incompatible types + | + = note: expected fn pointer `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` + found fn pointer `for<'a> fn(&'a u8, &'a u8) -> &'a u8` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nll.stderr b/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllnoleak.stderr similarity index 89% rename from src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nll.stderr rename to src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllnoleak.stderr index 5ac392914e57b..0d61311350e8c 100644 --- a/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nll.stderr +++ b/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllnoleak.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/old-lub-glb-hr-noteq1.rs:11:14 + --> $DIR/old-lub-glb-hr-noteq1.rs:17:14 | LL | _ => y, | ^ one type is more general than the other diff --git a/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.rs b/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.rs index 918542d471b58..2cf123cce7ffd 100644 --- a/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.rs +++ b/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.rs @@ -2,13 +2,23 @@ // general than the other. Test the case where the more general type (`x`) is the first // match arm specifically. +// revisions: baseleak basenoleak nllleak nllnoleak +// ignore-compare-mode-nll +//[nllleak] compile-flags: -Zborrowck=mir +//[nllnoleak] compile-flags: -Zborrowck=mir -Zno-leak-check +//[basenoleak] compile-flags:-Zno-leak-check + fn foo(x: for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8, y: for<'a> fn(&'a u8, &'a u8) -> &'a u8) { // The two types above are not equivalent. With the older LUB/GLB // algorithm, this may have worked (I don't remember), but now it // doesn't because we require equality. let z = match 22 { 0 => x, - _ => y, //~ ERROR `match` arms have incompatible types + _ => y, + //[baseleak]~^ ERROR `match` arms have incompatible types + //[nllleak]~^^ ERROR `match` arms have incompatible types + //[basenoleak]~^^^ ERROR `match` arms have incompatible types + //[nllnoleak]~^^^^ ERROR mismatched types }; } diff --git a/src/test/ui/lub-glb/old-lub-glb-hr-noteq2.stderr b/src/test/ui/lub-glb/old-lub-glb-hr-noteq2.baseleak.stderr similarity index 90% rename from src/test/ui/lub-glb/old-lub-glb-hr-noteq2.stderr rename to src/test/ui/lub-glb/old-lub-glb-hr-noteq2.baseleak.stderr index eacbbb8764025..1c9ce115e961e 100644 --- a/src/test/ui/lub-glb/old-lub-glb-hr-noteq2.stderr +++ b/src/test/ui/lub-glb/old-lub-glb-hr-noteq2.baseleak.stderr @@ -1,5 +1,5 @@ error[E0308]: `match` arms have incompatible types - --> $DIR/old-lub-glb-hr-noteq2.rs:21:14 + --> $DIR/old-lub-glb-hr-noteq2.rs:28:14 | LL | let z = match 22 { | _____________- @@ -7,6 +7,9 @@ LL | | 0 => y, | | - this is found to be of type `for<'a> fn(&'a u8, &'a u8) -> &'a u8` LL | | _ => x, | | ^ one type is more general than the other +LL | | +LL | | +LL | | LL | | }; | |_____- `match` arms have incompatible types | diff --git a/src/test/ui/lub-glb/old-lub-glb-hr-noteq2.basenoleak.stderr b/src/test/ui/lub-glb/old-lub-glb-hr-noteq2.basenoleak.stderr new file mode 100644 index 0000000000000..1c9ce115e961e --- /dev/null +++ b/src/test/ui/lub-glb/old-lub-glb-hr-noteq2.basenoleak.stderr @@ -0,0 +1,21 @@ +error[E0308]: `match` arms have incompatible types + --> $DIR/old-lub-glb-hr-noteq2.rs:28:14 + | +LL | let z = match 22 { + | _____________- +LL | | 0 => y, + | | - this is found to be of type `for<'a> fn(&'a u8, &'a u8) -> &'a u8` +LL | | _ => x, + | | ^ one type is more general than the other +LL | | +LL | | +LL | | +LL | | }; + | |_____- `match` arms have incompatible types + | + = note: expected fn pointer `for<'a> fn(&'a u8, &'a u8) -> &'a u8` + found fn pointer `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/lub-glb/old-lub-glb-hr-noteq2.nllleak.stderr b/src/test/ui/lub-glb/old-lub-glb-hr-noteq2.nllleak.stderr new file mode 100644 index 0000000000000..1c9ce115e961e --- /dev/null +++ b/src/test/ui/lub-glb/old-lub-glb-hr-noteq2.nllleak.stderr @@ -0,0 +1,21 @@ +error[E0308]: `match` arms have incompatible types + --> $DIR/old-lub-glb-hr-noteq2.rs:28:14 + | +LL | let z = match 22 { + | _____________- +LL | | 0 => y, + | | - this is found to be of type `for<'a> fn(&'a u8, &'a u8) -> &'a u8` +LL | | _ => x, + | | ^ one type is more general than the other +LL | | +LL | | +LL | | +LL | | }; + | |_____- `match` arms have incompatible types + | + = note: expected fn pointer `for<'a> fn(&'a u8, &'a u8) -> &'a u8` + found fn pointer `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/lub-glb/old-lub-glb-hr-noteq2.rs b/src/test/ui/lub-glb/old-lub-glb-hr-noteq2.rs index 2aabc0dab1edb..d49b85ce05ef7 100644 --- a/src/test/ui/lub-glb/old-lub-glb-hr-noteq2.rs +++ b/src/test/ui/lub-glb/old-lub-glb-hr-noteq2.rs @@ -2,15 +2,22 @@ // one is more general than the other. Test the case where the more general type // (`x`) is the second match arm specifically. // -// FIXME(#73154) Skip for compare-mode because the pure NLL checker accepts this -// test. (Note that it still errors in old-lub-glb-hr-noteq1.rs). What happens +// FIXME(#73154) Pure NLL checker without leak check accepts this test. +// (Note that it still errors in old-lub-glb-hr-noteq1.rs). What happens // is that, due to the ordering of the match arms, we pick the correct "more // general" fn type, and we ignore the errors from the non-NLL type checker that // requires equality. The NLL type checker only requires a subtyping -// relationship, and that holds. -// +// relationship, and that holds. To unblock landing NLL - and ensure that we can +// choose to make this always in error in the future - we perform the leak check +// after coercing a function pointer. + +// revisions: baseleak basenoleak nllleak nllnoleak // ignore-compare-mode-nll -// ignore-compare-mode-polonius +//[nllleak] compile-flags: -Zborrowck=mir +//[nllnoleak] compile-flags: -Zborrowck=mir -Zno-leak-check +//[basenoleak] compile-flags:-Zno-leak-check + +//[nllnoleak] check-pass fn foo(x: for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8, y: for<'a> fn(&'a u8, &'a u8) -> &'a u8) { // The two types above are not equivalent. With the older LUB/GLB @@ -18,7 +25,10 @@ fn foo(x: for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8, y: for<'a> fn(&'a u8, &'a u8 // doesn't because we require equality. let z = match 22 { 0 => y, - _ => x, //~ ERROR `match` arms have incompatible types + _ => x, + //[baseleak]~^ ERROR `match` arms have incompatible types + //[nllleak]~^^ ERROR `match` arms have incompatible types + //[basenoleak]~^^^ ERROR `match` arms have incompatible types }; } diff --git a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.base.stderr b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.base.stderr index 2ba4f4f5d9f46..b8b9de627af30 100644 --- a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.base.stderr +++ b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.base.stderr @@ -8,7 +8,7 @@ LL | *x = *y; | ^^ ...but data from `y` flows into `x` here error[E0623]: lifetime mismatch - --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:7 + --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:19:7 | LL | fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { | --------- --------- these two types are declared with different lifetimes... @@ -17,13 +17,13 @@ LL | a(x, y); | ^ ...but data from `y` flows into `x` here error[E0308]: mismatched types - --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:28:43 + --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:26:43 | LL | let _: fn(&mut &isize, &mut &isize) = a; | ^ one type is more general than the other | = note: expected fn pointer `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)` - found fn pointer `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)` + found fn item `for<'r, 's> fn(&'r mut &isize, &'s mut &isize) {a::<'_, '_>}` error: aborting due to 3 previous errors diff --git a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.nll.stderr b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.nll.stderr index c64309743346d..8a4b313264654 100644 --- a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.nll.stderr +++ b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.nll.stderr @@ -1,50 +1,12 @@ -error: lifetime may not live long enough - --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:12:5 - | -LL | fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -LL | // Illegal now because there is no `'b:'a` declaration. -LL | *x = *y; - | ^^^^^^^ assignment requires that `'b` must outlive `'a` - | - = help: consider adding the following bound: `'b: 'a` - -error: lifetime may not live long enough - --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:5 - | -LL | fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -... -LL | a(x, y); - | ^^^^^^^ argument requires that `'b` must outlive `'a` - | - = help: consider adding the following bound: `'b: 'a` - = note: requirement occurs because of a mutable reference to `&isize` - = note: mutable references are invariant over their type parameter - = help: see for more information about variance - -error[E0308]: mismatched types - --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:28:12 - | -LL | let _: fn(&mut &isize, &mut &isize) = a; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected fn pointer `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)` - found fn pointer `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)` - error[E0308]: mismatched types - --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:28:12 + --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:26:43 | LL | let _: fn(&mut &isize, &mut &isize) = a; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^ one type is more general than the other | = note: expected fn pointer `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)` - found fn pointer `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)` + found fn item `for<'r, 's> fn(&'r mut &isize, &'s mut &isize) {a::<'_, '_>}` -error: aborting due to 4 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs index ec91d1798083c..61ae1cc3fad6a 100644 --- a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs +++ b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs @@ -11,7 +11,6 @@ fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) { // Illegal now because there is no `'b:'a` declaration. *x = *y; //[base]~^ ERROR E0623 - //[nll]~^^ ERROR lifetime may not live long enough } fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { @@ -19,7 +18,6 @@ fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { // related as required. a(x, y); //[base]~^ ERROR lifetime mismatch [E0623] - //[nll]~^^ ERROR lifetime may not live long enough } fn d() { @@ -27,7 +25,6 @@ fn d() { // inconstraints: let _: fn(&mut &isize, &mut &isize) = a; //~^ ERROR mismatched types [E0308] - //[nll]~^^ ERROR mismatched types [E0308] } fn e() { diff --git a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.base.stderr b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.base.stderr index 537a1fb98a50f..062411e6f6890 100644 --- a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.base.stderr +++ b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.base.stderr @@ -8,7 +8,7 @@ LL | *x = *y; | ^^ ...but data from `y` flows into `x` here error[E0623]: lifetime mismatch - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:16:10 + --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:15:10 | LL | fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { | --------- --------- @@ -19,7 +19,7 @@ LL | *z = *y; | ^^ ...but data from `y` flows into `z` here error[E0623]: lifetime mismatch - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:7 + --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:21:7 | LL | fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { | --------- --------- these two types are declared with different lifetimes... @@ -28,13 +28,13 @@ LL | a(x, y, z); | ^ ...but data from `y` flows into `x` here error[E0308]: mismatched types - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:30:56 + --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:28:56 | LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; | ^ one type is more general than the other | = note: expected fn pointer `for<'r, 's, 't0, 't1, 't2, 't3> fn(&'r mut &'s isize, &'t0 mut &'t1 isize, &'t2 mut &'t3 isize)` - found fn pointer `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize)` + found fn item `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize) {a::<'_, '_, '_>}` error: aborting due to 4 previous errors diff --git a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.nll.stderr b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.nll.stderr index 053078f58df93..f304c69d44b5d 100644 --- a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.nll.stderr +++ b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.nll.stderr @@ -1,59 +1,12 @@ -error: lifetime may not live long enough - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:13:5 - | -LL | fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -LL | // Illegal now because there is no `'b:'a` declaration. -LL | *x = *y; - | ^^^^^^^ assignment requires that `'b` must outlive `'a` - | - = help: consider adding the following bound: `'b: 'a` - -error: lifetime may not live long enough - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:5 - | -LL | fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -... -LL | a(x, y, z); - | ^^^^^^^^^^ argument requires that `'b` must outlive `'a` - | - = help: consider adding the following bound: `'b: 'a` - = note: requirement occurs because of a mutable reference to `&isize` - = note: mutable references are invariant over their type parameter - = help: see for more information about variance - -error[E0308]: mismatched types - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:30:12 - | -LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected fn pointer `for<'r, 's, 't0, 't1, 't2, 't3> fn(&'r mut &'s isize, &'t0 mut &'t1 isize, &'t2 mut &'t3 isize)` - found fn pointer `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize)` - -error[E0308]: mismatched types - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:30:12 - | -LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected fn pointer `for<'r, 's, 't0, 't1, 't2, 't3> fn(&'r mut &'s isize, &'t0 mut &'t1 isize, &'t2 mut &'t3 isize)` - found fn pointer `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize)` - error[E0308]: mismatched types - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:30:12 + --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:28:56 | LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^ one type is more general than the other | = note: expected fn pointer `for<'r, 's, 't0, 't1, 't2, 't3> fn(&'r mut &'s isize, &'t0 mut &'t1 isize, &'t2 mut &'t3 isize)` - found fn pointer `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize)` + found fn item `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize) {a::<'_, '_, '_>}` -error: aborting due to 5 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs index 8b5c1d47ec61b..da225d842d9b0 100644 --- a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs +++ b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs @@ -12,7 +12,6 @@ fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { // Illegal now because there is no `'b:'a` declaration. *x = *y; //[base]~^ ERROR E0623 - //[nll]~^^ ERROR lifetime may not live long enough *z = *y; //[base]~ ERROR E0623 } @@ -21,7 +20,6 @@ fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { // related as required. a(x, y, z); //[base]~^ ERROR lifetime mismatch [E0623] - //[nll]~^^ ERROR lifetime may not live long enough } fn d() { @@ -29,8 +27,6 @@ fn d() { // inconstraints: let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; //~^ ERROR E0308 - //[nll]~^^ ERROR mismatched types [E0308] - //[nll]~| ERROR mismatched types [E0308] } fn e() { diff --git a/src/test/ui/regions/regions-fn-subtyping-return-static-fail.base.stderr b/src/test/ui/regions/regions-fn-subtyping-return-static-fail.base.stderr index 2182d8f661ff8..4616035870abf 100644 --- a/src/test/ui/regions/regions-fn-subtyping-return-static-fail.base.stderr +++ b/src/test/ui/regions/regions-fn-subtyping-return-static-fail.base.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/regions-fn-subtyping-return-static-fail.rs:52:12 | LL | want_G(baz); - | ^^^ one type is more general than the other + | ------ ^^^ one type is more general than the other + | | + | arguments to this function are incorrect | = note: expected fn pointer `for<'cx> fn(&'cx S) -> &'static S` - found fn pointer `for<'r> fn(&'r S) -> &'r S` + found fn item `for<'r> fn(&'r S) -> &'r S {baz}` +note: function defined here + --> $DIR/regions-fn-subtyping-return-static-fail.rs:24:4 + | +LL | fn want_G(f: G) {} + | ^^^^^^ ---- error: aborting due to previous error diff --git a/src/test/ui/regions/regions-fn-subtyping-return-static-fail.nll.stderr b/src/test/ui/regions/regions-fn-subtyping-return-static-fail.nll.stderr index 0bca2cfbefd9f..4616035870abf 100644 --- a/src/test/ui/regions/regions-fn-subtyping-return-static-fail.nll.stderr +++ b/src/test/ui/regions/regions-fn-subtyping-return-static-fail.nll.stderr @@ -1,11 +1,18 @@ error[E0308]: mismatched types - --> $DIR/regions-fn-subtyping-return-static-fail.rs:52:5 + --> $DIR/regions-fn-subtyping-return-static-fail.rs:52:12 | LL | want_G(baz); - | ^^^^^^^^^^^ one type is more general than the other + | ------ ^^^ one type is more general than the other + | | + | arguments to this function are incorrect | = note: expected fn pointer `for<'cx> fn(&'cx S) -> &'static S` - found fn pointer `for<'r> fn(&'r S) -> &'r S` + found fn item `for<'r> fn(&'r S) -> &'r S {baz}` +note: function defined here + --> $DIR/regions-fn-subtyping-return-static-fail.rs:24:4 + | +LL | fn want_G(f: G) {} + | ^^^^^^ ---- error: aborting due to previous error diff --git a/src/test/ui/regions/regions-lifetime-bounds-on-fns.base.stderr b/src/test/ui/regions/regions-lifetime-bounds-on-fns.base.stderr index e57b06aac3927..613e9af90a43f 100644 --- a/src/test/ui/regions/regions-lifetime-bounds-on-fns.base.stderr +++ b/src/test/ui/regions/regions-lifetime-bounds-on-fns.base.stderr @@ -8,7 +8,7 @@ LL | *x = *y; | ^^ ...but data from `y` flows into `x` here error[E0623]: lifetime mismatch - --> $DIR/regions-lifetime-bounds-on-fns.rs:20:7 + --> $DIR/regions-lifetime-bounds-on-fns.rs:19:7 | LL | fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { | --------- --------- these two types are declared with different lifetimes... @@ -17,13 +17,13 @@ LL | a(x, y); | ^ ...but data from `y` flows into `x` here error[E0308]: mismatched types - --> $DIR/regions-lifetime-bounds-on-fns.rs:28:43 + --> $DIR/regions-lifetime-bounds-on-fns.rs:26:43 | LL | let _: fn(&mut &isize, &mut &isize) = a; | ^ one type is more general than the other | = note: expected fn pointer `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)` - found fn pointer `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)` + found fn item `for<'r, 's> fn(&'r mut &isize, &'s mut &isize) {a::<'_, '_>}` error: aborting due to 3 previous errors diff --git a/src/test/ui/regions/regions-lifetime-bounds-on-fns.nll.stderr b/src/test/ui/regions/regions-lifetime-bounds-on-fns.nll.stderr index 7fe8b4bf57fc1..268a60968b734 100644 --- a/src/test/ui/regions/regions-lifetime-bounds-on-fns.nll.stderr +++ b/src/test/ui/regions/regions-lifetime-bounds-on-fns.nll.stderr @@ -1,50 +1,12 @@ -error: lifetime may not live long enough - --> $DIR/regions-lifetime-bounds-on-fns.rs:12:5 - | -LL | fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -LL | // Illegal now because there is no `'b:'a` declaration. -LL | *x = *y; - | ^^^^^^^ assignment requires that `'b` must outlive `'a` - | - = help: consider adding the following bound: `'b: 'a` - -error: lifetime may not live long enough - --> $DIR/regions-lifetime-bounds-on-fns.rs:20:5 - | -LL | fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -... -LL | a(x, y); - | ^^^^^^^ argument requires that `'b` must outlive `'a` - | - = help: consider adding the following bound: `'b: 'a` - = note: requirement occurs because of a mutable reference to `&isize` - = note: mutable references are invariant over their type parameter - = help: see for more information about variance - -error[E0308]: mismatched types - --> $DIR/regions-lifetime-bounds-on-fns.rs:28:12 - | -LL | let _: fn(&mut &isize, &mut &isize) = a; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected fn pointer `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)` - found fn pointer `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)` - error[E0308]: mismatched types - --> $DIR/regions-lifetime-bounds-on-fns.rs:28:12 + --> $DIR/regions-lifetime-bounds-on-fns.rs:26:43 | LL | let _: fn(&mut &isize, &mut &isize) = a; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^ one type is more general than the other | = note: expected fn pointer `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)` - found fn pointer `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)` + found fn item `for<'r, 's> fn(&'r mut &isize, &'s mut &isize) {a::<'_, '_>}` -error: aborting due to 4 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/regions/regions-lifetime-bounds-on-fns.rs b/src/test/ui/regions/regions-lifetime-bounds-on-fns.rs index 97c08d8ab0e3c..ef5e5cb12ef10 100644 --- a/src/test/ui/regions/regions-lifetime-bounds-on-fns.rs +++ b/src/test/ui/regions/regions-lifetime-bounds-on-fns.rs @@ -11,7 +11,6 @@ fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) { // Illegal now because there is no `'b:'a` declaration. *x = *y; //[base]~^ ERROR lifetime mismatch [E0623] - //[nll]~^^ ERROR lifetime may not live long enough } fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { @@ -19,7 +18,6 @@ fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { // related as required. a(x, y); //[base]~^ ERROR lifetime mismatch [E0623] - //[nll]~^^ ERROR lifetime may not live long enough } fn d() { @@ -27,7 +25,6 @@ fn d() { // inconstraints: let _: fn(&mut &isize, &mut &isize) = a; //~^ ERROR mismatched types [E0308] - //[nll]~^^ ERROR mismatched types [E0308] } fn e() {