diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 6cce3a56f081d..6ed5fc77d75f4 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -28,7 +28,7 @@ pub fn rust_version_symbol() -> Symbol { } pub fn is_builtin_attr(attr: &Attribute) -> bool { - attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some() + attr.is_doc_comment() || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name)) } enum AttrError { diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 03b90f4ab184e..28c0a444fc873 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -2133,13 +2133,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.current -= 1; } fn visit_expr(&mut self, expr: &hir::Expr<'tcx>) { - if self.span == expr.span { + if self.span == expr.span.source_callsite() { self.found = self.current; } walk_expr(self, expr); } } let source_info = self.body.source_info(location); + let proper_span = proper_span.source_callsite(); if let Some(scope) = self.body.source_scopes.get(source_info.scope) && let ClearCrossCrate::Set(scope_data) = &scope.local_data && let Some(node) = self.infcx.tcx.hir().find(scope_data.lint_root) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 3235a9ceba1f0..bc109e7ad5170 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1462,7 +1462,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let traits: Vec<_> = self.probe_traits_that_match_assoc_ty(qself_ty, assoc_ident); - // Don't print `TyErr` to the user. + // Don't print `ty::Error` to the user. self.report_ambiguous_associated_type( span, &[qself_ty.to_string()], diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index ad886ce82b142..6206ba508aed1 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -555,8 +555,8 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable>>( for (region_a, region_a_idx) in ®ions { // Ignore `'static` lifetimes for the purpose of this lint: it's // because we know it outlives everything and so doesn't give meaningful - // clues - if let ty::ReStatic = **region_a { + // clues. Also ignore `ReError`, to avoid knock-down errors. + if let ty::ReStatic | ty::ReError(_) = **region_a { continue; } // For each region argument (e.g., `'a` in our example), check for a @@ -599,8 +599,9 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable>>( // on the GAT itself. for (region_b, region_b_idx) in ®ions { // Again, skip `'static` because it outlives everything. Also, we trivially - // know that a region outlives itself. - if ty::ReStatic == **region_b || region_a == region_b { + // know that a region outlives itself. Also ignore `ReError`, to avoid + // knock-down errors. + if matches!(**region_b, ty::ReStatic | ty::ReError(_)) || region_a == region_b { continue; } if region_known_to_outlive( diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 0624a4baf79db..3e67afb1c3d9b 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -795,7 +795,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Converts the types that the user supplied, in case that doing /// so should yield an error, but returns back a signature where - /// all parameters are of type `TyErr`. + /// all parameters are of type `ty::Error`. fn error_sig_of_closure( &self, decl: &hir::FnDecl<'_>, diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 5a78790ec6e1c..25077f9bb97ee 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2567,15 +2567,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { None, ); if let Some(infer::RelateParamBound(_, t, _)) = origin { - let return_impl_trait = - self.tcx.return_type_impl_trait(generic_param_scope).is_some(); let t = self.resolve_vars_if_possible(t); match t.kind() { // We've got: // fn get_later(g: G, dest: &mut T) -> impl FnOnce() + '_ // suggest: // fn get_later<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a - ty::Closure(..) | ty::Alias(ty::Opaque, ..) if return_impl_trait => { + ty::Closure(..) | ty::Alias(ty::Opaque, ..) => { new_binding_suggestion(&mut err, type_param_span); } _ => { diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index be424424f3ae8..60d9d6578f54d 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -942,6 +942,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { generic_ty: Ty<'tcx>, min: ty::Region<'tcx>, ) -> bool { + if let ty::ReError(_) = *min { + return true; + } + match bound { VerifyBound::IfEq(verify_if_eq_b) => { let verify_if_eq_b = var_values.normalize(self.region_rels.tcx, *verify_if_eq_b); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 63df2830e0aa9..1189dcdfcbb3a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -706,7 +706,7 @@ rustc_queries! { separate_provide_extern } - query adt_sized_constraint(key: DefId) -> &'tcx [Ty<'tcx>] { + query adt_sized_constraint(key: DefId) -> ty::EarlyBinder<&'tcx ty::List>> { desc { |tcx| "computing `Sized` constraints for `{}`", tcx.def_path_str(key) } } diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index e067d2a984fde..6ba13a76563b3 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -562,18 +562,10 @@ impl<'tcx> AdtDef<'tcx> { tcx.adt_destructor(self.did()) } - /// Returns a list of types such that `Self: Sized` if and only - /// if that type is `Sized`, or `TyErr` if this type is recursive. - /// - /// Oddly enough, checking that the sized-constraint is `Sized` is - /// actually more expressive than checking all members: - /// the `Sized` trait is inductive, so an associated type that references - /// `Self` would prevent its containing ADT from being `Sized`. - /// - /// Due to normalization being eager, this applies even if - /// the associated type is behind a pointer (e.g., issue #31299). - pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> ty::EarlyBinder<&'tcx [Ty<'tcx>]> { - ty::EarlyBinder::bind(tcx.adt_sized_constraint(self.did())) + /// Returns a list of types such that `Self: Sized` if and only if that + /// type is `Sized`, or `ty::Error` if this type has a recursive layout. + pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> ty::EarlyBinder<&'tcx ty::List>> { + tcx.adt_sized_constraint(self.did()) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index aa1f8e48b1b79..5eef3e45f327a 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -50,9 +50,7 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::definitions::Definitions; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; -use rustc_hir::{ - Constness, ExprKind, HirId, ImplItemKind, ItemKind, Node, TraitCandidate, TraitItemKind, -}; +use rustc_hir::{Constness, HirId, Node, TraitCandidate}; use rustc_index::IndexVec; use rustc_macros::HashStable; use rustc_query_system::dep_graph::DepNodeIndex; @@ -1077,31 +1075,6 @@ impl<'tcx> TyCtxt<'tcx> { return None; } - pub fn return_type_impl_trait(self, scope_def_id: LocalDefId) -> Option<(Ty<'tcx>, Span)> { - // `type_of()` will fail on these (#55796, #86483), so only allow `fn`s or closures. - match self.hir().get_by_def_id(scope_def_id) { - Node::Item(&hir::Item { kind: ItemKind::Fn(..), .. }) => {} - Node::TraitItem(&hir::TraitItem { kind: TraitItemKind::Fn(..), .. }) => {} - Node::ImplItem(&hir::ImplItem { kind: ImplItemKind::Fn(..), .. }) => {} - Node::Expr(&hir::Expr { kind: ExprKind::Closure { .. }, .. }) => {} - _ => return None, - } - - let ret_ty = self.type_of(scope_def_id).instantiate_identity(); - match ret_ty.kind() { - ty::FnDef(_, _) => { - let sig = ret_ty.fn_sig(self); - let output = self.erase_late_bound_regions(sig.output()); - output.is_impl_trait().then(|| { - let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id); - let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap(); - (output, fn_decl.output.span()) - }) - } - _ => None, - } - } - /// Checks if the bound region is in Impl Item. pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool { let container_id = self.parent(suitable_region_binding_scope.to_def_id()); diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index a2db35e069eb7..72ba4f5913780 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -150,7 +150,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>( ty::Adt(def, args) => { let sized_crit = def.sized_constraint(ecx.tcx()); - Ok(sized_crit.iter_instantiated_copied(ecx.tcx(), args).collect()) + Ok(sized_crit.iter_instantiated(ecx.tcx(), args).collect()) } } } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs index 1aef9a885bc06..8a3c7b22e3287 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs @@ -235,7 +235,10 @@ fn rematch_unsize<'tcx>( goal.param_env, &mut nested, ); + match (a_ty.kind(), b_ty.kind()) { + // Don't try to coerce `?0` to `dyn Trait` + (ty::Infer(ty::TyVar(_)), _) | (_, ty::Infer(ty::TyVar(_))) => Ok(None), // Stall any ambiguous upcasting goals, since we can't rematch those (ty::Dynamic(_, _, ty::Dyn), ty::Dynamic(_, _, ty::Dyn)) => match certainty { Certainty::Yes => Ok(Some(ImplSource::Builtin(source, nested))), diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 14020c05251d5..95485850d0e9b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -3030,8 +3030,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.report_similar_impl_candidates_for_root_obligation(&obligation, *trait_predicate, body_def_id, err); } - self.maybe_suggest_convert_to_slice( + self.suggest_convert_to_slice( err, + obligation, trait_ref, impl_candidates.as_slice(), span, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 31f70bbd34dec..46c31c77613ef 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -398,9 +398,10 @@ pub trait TypeErrCtxtExt<'tcx> { param_env: ty::ParamEnv<'tcx>, ) -> Vec))>>; - fn maybe_suggest_convert_to_slice( + fn suggest_convert_to_slice( &self, err: &mut Diagnostic, + obligation: &PredicateObligation<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, candidate_impls: &[ImplCandidate<'tcx>], span: Span, @@ -3944,13 +3945,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { /// If the type that failed selection is an array or a reference to an array, /// but the trait is implemented for slices, suggest that the user converts /// the array into a slice. - fn maybe_suggest_convert_to_slice( + fn suggest_convert_to_slice( &self, err: &mut Diagnostic, + obligation: &PredicateObligation<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, candidate_impls: &[ImplCandidate<'tcx>], span: Span, ) { + // We can only suggest the slice coersion for function arguments since the suggestion + // would make no sense in turbofish or call + let ObligationCauseCode::FunctionArgumentObligation { .. } = obligation.cause.code() else { + return; + }; + // Three cases where we can make a suggestion: // 1. `[T; _]` (array of T) // 2. `&[T; _]` (reference to array of T) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index c29696bc817f7..6080a440de6b6 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2099,7 +2099,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { Where( obligation .predicate - .rebind(sized_crit.iter_instantiated_copied(self.tcx(), args).collect()), + .rebind(sized_crit.iter_instantiated(self.tcx(), args).collect()), ) } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 791a1f4fa99a2..ba0258b63cb62 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -42,7 +42,7 @@ fn sized_constraint_for_ty<'tcx>( let adt_tys = adt.sized_constraint(tcx); debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", ty, adt_tys); adt_tys - .iter_instantiated_copied(tcx, args) + .iter_instantiated(tcx, args) .flat_map(|ty| sized_constraint_for_ty(tcx, adtdef, ty)) .collect() } @@ -58,11 +58,18 @@ fn sized_constraint_for_ty<'tcx>( // we know that `T` is Sized and do not need to check // it on the impl. - let Some(sized_trait) = tcx.lang_items().sized_trait() else { return vec![ty] }; - let sized_predicate = - ty::TraitRef::new(tcx, sized_trait, [ty]).without_const().to_predicate(tcx); + let Some(sized_trait_def_id) = tcx.lang_items().sized_trait() else { return vec![ty] }; let predicates = tcx.predicates_of(adtdef.did()).predicates; - if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] } + if predicates.iter().any(|(p, _)| { + p.as_trait_clause().is_some_and(|trait_pred| { + trait_pred.def_id() == sized_trait_def_id + && trait_pred.self_ty().skip_binder() == ty + }) + }) { + vec![] + } else { + vec![ty] + } } Placeholder(..) | Bound(..) | Infer(..) => { @@ -92,10 +99,13 @@ fn defaultness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Defaultness { /// - a tuple of type parameters or projections, if there are multiple /// such. /// - an Error, if a type is infinitely sized -fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] { +fn adt_sized_constraint<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, +) -> ty::EarlyBinder<&'tcx ty::List>> { if let Some(def_id) = def_id.as_local() { if matches!(tcx.representability(def_id), ty::Representability::Infinite) { - return tcx.mk_type_list(&[Ty::new_misc_error(tcx)]); + return ty::EarlyBinder::bind(tcx.mk_type_list(&[Ty::new_misc_error(tcx)])); } } let def = tcx.adt_def(def_id); @@ -107,7 +117,7 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] { debug!("adt_sized_constraint: {:?} => {:?}", def, result); - result + ty::EarlyBinder::bind(result) } /// See `ParamEnv` struct definition for details. diff --git a/tests/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr b/tests/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr index 4eeec09b91040..6e112e2703003 100644 --- a/tests/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr +++ b/tests/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr @@ -8,8 +8,12 @@ LL | let x = defer(&vec!["Goodbye", "world!"]); LL | x.x[0]; | ------ borrow later used here | - = note: consider using a `let` binding to create a longer lived value = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = vec!["Goodbye", "world!"]; +LL ~ let x = defer(&binding); + | error: aborting due to previous error diff --git a/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.rs b/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.rs new file mode 100644 index 0000000000000..c6ef8379f455c --- /dev/null +++ b/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.rs @@ -0,0 +1,13 @@ +trait Test {} +impl Test for &[u8] {} + +fn needs_test() -> T { + panic!() +} + +fn main() { + needs_test::<[u8; 1]>(); + //~^ ERROR the trait bound + let x: [u8; 1] = needs_test(); + //~^ ERROR the trait bound +} diff --git a/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.stderr b/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.stderr new file mode 100644 index 0000000000000..6752a484448c5 --- /dev/null +++ b/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.stderr @@ -0,0 +1,29 @@ +error[E0277]: the trait bound `[u8; 1]: Test` is not satisfied + --> $DIR/issue-90528-unsizing-not-suggestion-110063.rs:9:18 + | +LL | needs_test::<[u8; 1]>(); + | ^^^^^^^ the trait `Test` is not implemented for `[u8; 1]` + | + = help: the trait `Test` is implemented for `&[u8]` +note: required by a bound in `needs_test` + --> $DIR/issue-90528-unsizing-not-suggestion-110063.rs:4:18 + | +LL | fn needs_test() -> T { + | ^^^^ required by this bound in `needs_test` + +error[E0277]: the trait bound `[u8; 1]: Test` is not satisfied + --> $DIR/issue-90528-unsizing-not-suggestion-110063.rs:11:22 + | +LL | let x: [u8; 1] = needs_test(); + | ^^^^^^^^^^ the trait `Test` is not implemented for `[u8; 1]` + | + = help: the trait `Test` is implemented for `&[u8]` +note: required by a bound in `needs_test` + --> $DIR/issue-90528-unsizing-not-suggestion-110063.rs:4:18 + | +LL | fn needs_test() -> T { + | ^^^^ required by this bound in `needs_test` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.rs b/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.rs new file mode 100644 index 0000000000000..abc845d3afa39 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.rs @@ -0,0 +1,12 @@ +#![feature(return_position_impl_trait_in_trait)] + +trait Iterable { + type Item<'a> + where + Self: 'a; + + fn iter(&self) -> impl Iterator>; + //~^ ERROR use of undeclared lifetime name `'missing` +} + +fn main() {} diff --git a/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.stderr b/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.stderr new file mode 100644 index 0000000000000..0d74c0b69ce06 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.stderr @@ -0,0 +1,23 @@ +error[E0261]: use of undeclared lifetime name `'missing` + --> $DIR/missing-lt-outlives-in-rpitit-114274.rs:8:55 + | +LL | fn iter(&self) -> impl Iterator>; + | ^^^^^^^^ undeclared lifetime + | + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider making the bound lifetime-generic with a new `'missing` lifetime + | +LL | fn iter(&self) -> impl for<'missing> Iterator>; + | +++++++++++++ +help: consider introducing lifetime `'missing` here + | +LL | fn iter<'missing>(&self) -> impl Iterator>; + | ++++++++++ +help: consider introducing lifetime `'missing` here + | +LL | trait Iterable<'missing> { + | ++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/inference/type-infer-generalize-ty-var.rs b/tests/ui/inference/type-infer-generalize-ty-var.rs index a3d6916cbf760..8b4a8c32bb225 100644 --- a/tests/ui/inference/type-infer-generalize-ty-var.rs +++ b/tests/ui/inference/type-infer-generalize-ty-var.rs @@ -1,4 +1,6 @@ -// run-pass +// check-pass +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next #![allow(non_upper_case_globals)] #![allow(dead_code)] diff --git a/tests/ui/lifetimes/borrowck-let-suggestion.stderr b/tests/ui/lifetimes/borrowck-let-suggestion.stderr index 38fd92d761949..da0078698ae3b 100644 --- a/tests/ui/lifetimes/borrowck-let-suggestion.stderr +++ b/tests/ui/lifetimes/borrowck-let-suggestion.stderr @@ -9,8 +9,12 @@ LL | LL | x.use_mut(); | - borrow later used here | - = note: consider using a `let` binding to create a longer lived value = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = vec![1]; +LL ~ let mut x = binding.iter(); + | error: aborting due to previous error diff --git a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr index 4ecc6370d3caa..9df7f0ffd0c3f 100644 --- a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr +++ b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr @@ -9,8 +9,12 @@ LL | LL | stuff(phantom_pinned) | -------------- borrow later used here | - = note: consider using a `let` binding to create a longer lived value = note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = pin!(PhantomPinned); +LL ~ let phantom_pinned = identity(binding); + | error[E0716]: temporary value dropped while borrowed --> $DIR/lifetime_errors_on_promotion_misusage.rs:18:30 diff --git a/tests/ui/traits/new-solver/dont-coerce-infer-to-dyn.rs b/tests/ui/traits/new-solver/dont-coerce-infer-to-dyn.rs new file mode 100644 index 0000000000000..c2ac80459caac --- /dev/null +++ b/tests/ui/traits/new-solver/dont-coerce-infer-to-dyn.rs @@ -0,0 +1,17 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +use std::fmt::Display; +use std::rc::Rc; + +fn mk(t: Option<&T>) -> Rc { + todo!() +} + +fn main() { + let mut x = None; + let y = mk(x); + // Don't treat the line below as a unsize coercion `Rc ~> Rc` + let z: Rc = y; + x = Some(&1 as &dyn Display); +}