Skip to content

Rollup of 6 pull requests #103228

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Oct 19, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion compiler/rustc_hir_analysis/src/check/callee.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::method::probe::{IsSuggestion, Mode, ProbeScope};
use super::method::MethodCallee;
use super::{DefIdOrName, Expectation, FnCtxt, TupleArgumentsFlag};
use super::{Expectation, FnCtxt, TupleArgumentsFlag};
use crate::type_error_struct;

use rustc_ast::util::parser::PREC_POSTFIX;
@@ -27,6 +27,7 @@ use rustc_span::Span;
use rustc_target::spec::abi;
use rustc_trait_selection::autoderef::Autoderef;
use rustc_trait_selection::infer::InferCtxtExt as _;
use rustc_trait_selection::traits::error_reporting::DefIdOrName;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;

use std::iter;
15 changes: 4 additions & 11 deletions compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,6 @@ use super::FnCtxt;
use crate::astconv::AstConv;
use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel};

use hir::def_id::DefId;
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
use rustc_errors::{Applicability, Diagnostic, MultiSpan};
use rustc_hir as hir;
@@ -19,6 +18,7 @@ use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::DefIdOrName;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -90,7 +90,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if ty.is_suggestable(self.tcx, false) {
format!("/* {ty} */")
} else {
"".to_string()
"/* value */".to_string()
}
})
.collect::<Vec<_>>()
@@ -102,10 +102,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

let msg = match def_id_or_name {
DefIdOrName::DefId(def_id) => match self.tcx.def_kind(def_id) {
DefKind::Ctor(CtorOf::Struct, _) => "instantiate this tuple struct".to_string(),
DefKind::Ctor(CtorOf::Variant, _) => {
"instantiate this tuple variant".to_string()
}
DefKind::Ctor(CtorOf::Struct, _) => "construct this tuple struct".to_string(),
DefKind::Ctor(CtorOf::Variant, _) => "construct this tuple variant".to_string(),
kind => format!("call this {}", kind.descr(def_id)),
},
DefIdOrName::Name(name) => format!("call this {name}"),
@@ -1209,8 +1207,3 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
}

pub enum DefIdOrName {
DefId(DefId),
Name(&'static str),
}
8 changes: 6 additions & 2 deletions compiler/rustc_hir_analysis/src/check/region.rs
Original file line number Diff line number Diff line change
@@ -252,9 +252,13 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
) => {
// For shortcircuiting operators, mark the RHS as a terminating
// scope since it only executes conditionally.
terminating(r.hir_id.local_id);
}

// `Let` expressions (in a let-chain) shouldn't be terminating, as their temporaries
// should live beyond the immediate expression
if !matches!(r.kind, hir::ExprKind::Let(_)) {
terminating(r.hir_id.local_id);
}
}
hir::ExprKind::If(_, ref then, Some(ref otherwise)) => {
terminating(then.hir_id.local_id);
terminating(otherwise.hir_id.local_id);
181 changes: 92 additions & 89 deletions compiler/rustc_middle/src/query/mod.rs

Large diffs are not rendered by default.

17 changes: 11 additions & 6 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
@@ -1862,9 +1862,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
for (index, (pat, ty)) in inputs.enumerate() {
debug!(?pat, ?ty);
if let Some(pat) = pat {
self.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
}
self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
if let Some(pat) = pat {
this.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
}
});
self.visit_ty(ty);

if let Some(ref candidates) = self.lifetime_elision_candidates {
@@ -2834,10 +2836,13 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {

fn resolve_params(&mut self, params: &'ast [Param]) {
let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
for Param { pat, ty, .. } in params {
self.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
for Param { pat, .. } in params {
this.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
}
});
for Param { ty, .. } in params {
self.visit_ty(ty);
debug!("(resolving function / closure) recorded parameter");
}
}

13 changes: 9 additions & 4 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
@@ -2,10 +2,10 @@ pub mod on_unimplemented;
pub mod suggestions;

use super::{
EvaluationResult, FulfillmentContext, FulfillmentError, FulfillmentErrorCode,
MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode,
OnUnimplementedDirective, OnUnimplementedNote, OutputTypeParameterMismatch, Overflow,
PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe,
FulfillmentContext, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes,
Obligation, ObligationCause, ObligationCauseCode, OnUnimplementedDirective,
OnUnimplementedNote, OutputTypeParameterMismatch, Overflow, PredicateObligation,
SelectionContext, SelectionError, TraitNotObjectSafe,
};

use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
@@ -2796,3 +2796,8 @@ impl<'tcx> ty::TypeVisitor<'tcx> for HasNumericInferVisitor {
}
}
}

pub enum DefIdOrName {
DefId(DefId),
Name(&'static str),
}
217 changes: 153 additions & 64 deletions compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use super::{
EvaluationResult, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation,
DefIdOrName, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation,
SelectionContext,
};

use crate::autoderef::Autoderef;
use crate::infer::InferCtxt;
use crate::traits::normalize_to;

use hir::def::CtorOf;
use hir::HirId;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -22,14 +23,15 @@ use rustc_hir::lang_items::LangItem;
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::LateBoundRegionConversionTime;
use rustc_middle::hir::map;
use rustc_middle::ty::{
self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, IsSuggestable,
ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
};
use rustc_middle::ty::{TypeAndMut, TypeckResults};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{BytePos, DesugaringKind, ExpnKind, Span, DUMMY_SP};
use rustc_target::spec::abi;
use std::fmt;
@@ -812,74 +814,136 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> bool {
// Skipping binder here, remapping below
let self_ty = trait_pred.self_ty().skip_binder();

let (def_id, output_ty, callable) = match *self_ty.kind() {
ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig().output(), "closure"),
ty::FnDef(def_id, _) => (def_id, self_ty.fn_sig(self.tcx).output(), "function"),
_ => return false,
};
let msg = format!("use parentheses to call the {}", callable);
if let ty::PredicateKind::Trait(trait_pred) = obligation.predicate.kind().skip_binder()
&& Some(trait_pred.def_id()) == self.tcx.lang_items().sized_trait()
{
// Don't suggest calling to turn an unsized type into a sized type
return false;
}

// "We should really create a single list of bound vars from the combined vars
// from the predicate and function, but instead we just liberate the function bound vars"
let output_ty = self.tcx.liberate_late_bound_regions(def_id, output_ty);
// This is duplicated from `extract_callable_info` in typeck, which
// relies on autoderef, so we can't use it here.
let found = trait_pred.self_ty().skip_binder().peel_refs();
let Some((def_id_or_name, output, inputs)) = (match *found.kind()
{
ty::FnPtr(fn_sig) => {
Some((DefIdOrName::Name("function pointer"), fn_sig.output(), fn_sig.inputs()))
}
ty::FnDef(def_id, _) => {
let fn_sig = found.fn_sig(self.tcx);
Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs()))
}
ty::Closure(def_id, substs) => {
let fn_sig = substs.as_closure().sig();
Some((
DefIdOrName::DefId(def_id),
fn_sig.output(),
fn_sig.inputs().map_bound(|inputs| &inputs[1..]),
))
}
ty::Opaque(def_id, substs) => {
self.tcx.bound_item_bounds(def_id).subst(self.tcx, substs).iter().find_map(|pred| {
if let ty::PredicateKind::Projection(proj) = pred.kind().skip_binder()
&& Some(proj.projection_ty.item_def_id) == self.tcx.lang_items().fn_once_output()
// args tuple will always be substs[1]
&& let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
{
Some((
DefIdOrName::DefId(def_id),
pred.kind().rebind(proj.term.ty().unwrap()),
pred.kind().rebind(args.as_slice()),
))
} else {
None
}
})
}
ty::Dynamic(data, _, ty::Dyn) => {
data.iter().find_map(|pred| {
if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder()
&& Some(proj.item_def_id) == self.tcx.lang_items().fn_once_output()
// for existential projection, substs are shifted over by 1
&& let ty::Tuple(args) = proj.substs.type_at(0).kind()
{
Some((
DefIdOrName::Name("trait object"),
pred.rebind(proj.term.ty().unwrap()),
pred.rebind(args.as_slice()),
))
} else {
None
}
})
}
ty::Param(_) => {
obligation.param_env.caller_bounds().iter().find_map(|pred| {
if let ty::PredicateKind::Projection(proj) = pred.kind().skip_binder()
&& Some(proj.projection_ty.item_def_id) == self.tcx.lang_items().fn_once_output()
&& proj.projection_ty.self_ty() == found
// args tuple will always be substs[1]
&& let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
{
Some((
DefIdOrName::Name("type parameter"),
pred.kind().rebind(proj.term.ty().unwrap()),
pred.kind().rebind(args.as_slice()),
))
} else {
None
}
})
}
_ => None,
}) else { return false; };
let output = self.replace_bound_vars_with_fresh_vars(
obligation.cause.span,
LateBoundRegionConversionTime::FnCall,
output,
);
let inputs = inputs.skip_binder().iter().map(|ty| {
self.replace_bound_vars_with_fresh_vars(
obligation.cause.span,
LateBoundRegionConversionTime::FnCall,
inputs.rebind(*ty),
)
});

// Remapping bound vars here
let trait_pred_and_self = trait_pred.map_bound(|trait_pred| (trait_pred, output_ty));
let trait_pred_and_self = trait_pred.map_bound(|trait_pred| (trait_pred, output));

let new_obligation =
self.mk_trait_obligation_with_new_self_ty(obligation.param_env, trait_pred_and_self);

match self.evaluate_obligation(&new_obligation) {
Ok(
EvaluationResult::EvaluatedToOk
| EvaluationResult::EvaluatedToOkModuloRegions
| EvaluationResult::EvaluatedToOkModuloOpaqueTypes
| EvaluationResult::EvaluatedToAmbig,
) => {}
_ => return false,
if !self.predicate_must_hold_modulo_regions(&new_obligation) {
return false;
}
let hir = self.tcx.hir();

// Get the name of the callable and the arguments to be used in the suggestion.
let (snippet, sugg) = match hir.get_if_local(def_id) {
Some(hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure(hir::Closure { fn_decl, fn_decl_span, .. }),
..
})) => {
err.span_label(*fn_decl_span, "consider calling this closure");
let Some(name) = self.get_closure_name(def_id, err, &msg) else {
return false;
};
let args = fn_decl.inputs.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
let sugg = format!("({})", args);
(format!("{}{}", name, sugg), sugg)
}
Some(hir::Node::Item(hir::Item {
ident,
kind: hir::ItemKind::Fn(.., body_id),
..
})) => {
err.span_label(ident.span, "consider calling this function");
let body = hir.body(*body_id);
let args = body
.params
.iter()
.map(|arg| match &arg.pat.kind {
hir::PatKind::Binding(_, _, ident, None)
// FIXME: provide a better suggestion when encountering `SelfLower`, it
// should suggest a method call.
if ident.name != kw::SelfLower => ident.to_string(),
_ => "_".to_string(),
})
.collect::<Vec<_>>()
.join(", ");
let sugg = format!("({})", args);
(format!("{}{}", ident, sugg), sugg)
}
_ => return false,
let hir = self.tcx.hir();

let msg = match def_id_or_name {
DefIdOrName::DefId(def_id) => match self.tcx.def_kind(def_id) {
DefKind::Ctor(CtorOf::Struct, _) => {
"use parentheses to construct this tuple struct".to_string()
}
DefKind::Ctor(CtorOf::Variant, _) => {
"use parentheses to construct this tuple variant".to_string()
}
kind => format!("use parentheses to call this {}", kind.descr(def_id)),
},
DefIdOrName::Name(name) => format!("use parentheses to call this {name}"),
};

let args = inputs
.map(|ty| {
if ty.is_suggestable(self.tcx, false) {
format!("/* {ty} */")
} else {
"/* value */".to_string()
}
})
.collect::<Vec<_>>()
.join(", ");

if matches!(obligation.cause.code(), ObligationCauseCode::FunctionArgumentObligation { .. })
&& obligation.cause.span.can_be_used_for_suggestions()
{
@@ -890,11 +954,36 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err.span_suggestion_verbose(
obligation.cause.span.shrink_to_hi(),
&msg,
sugg,
format!("({args})"),
Applicability::HasPlaceholders,
);
} else {
err.help(&format!("{}: `{}`", msg, snippet));
} else if let DefIdOrName::DefId(def_id) = def_id_or_name {
let name = match hir.get_if_local(def_id) {
Some(hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure(hir::Closure { fn_decl_span, .. }),
..
})) => {
err.span_label(*fn_decl_span, "consider calling this closure");
let Some(name) = self.get_closure_name(def_id, err, &msg) else {
return false;
};
name.to_string()
}
Some(hir::Node::Item(hir::Item { ident, kind: hir::ItemKind::Fn(..), .. })) => {
err.span_label(ident.span, "consider calling this function");
ident.to_string()
}
Some(hir::Node::Ctor(..)) => {
let name = self.tcx.def_path_str(def_id);
err.span_label(
self.tcx.def_span(def_id),
format!("consider calling the constructor for `{}`", name),
);
name
}
_ => return false,
};
err.help(&format!("{msg}: `{name}({args})`"));
}
true
}
1 change: 0 additions & 1 deletion library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
@@ -2193,7 +2193,6 @@ impl<T, A: Allocator> Vec<T, A> {
/// static_ref[0] += 1;
/// assert_eq!(static_ref, &[2, 2, 3]);
/// ```
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "vec_leak", since = "1.47.0")]
#[inline]
pub fn leak<'a>(self) -> &'a mut [T]
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -217,6 +217,7 @@
#![feature(unboxed_closures)]
#![feature(unsized_fn_params)]
#![feature(asm_const)]
#![feature(const_transmute_copy)]
//
// Target features:
#![feature(arm_target_feature)]
6 changes: 4 additions & 2 deletions library/core/src/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
@@ -1297,7 +1297,8 @@ impl<T, const N: usize> MaybeUninit<[T; N]> {
/// let data: [MaybeUninit<u8>; 1000] = MaybeUninit::uninit().transpose();
/// ```
#[unstable(feature = "maybe_uninit_uninit_array_transpose", issue = "96097")]
pub fn transpose(self) -> [MaybeUninit<T>; N] {
#[inline]
pub const fn transpose(self) -> [MaybeUninit<T>; N] {
// SAFETY: T and MaybeUninit<T> have the same layout
unsafe { super::transmute_copy(&ManuallyDrop::new(self)) }
}
@@ -1316,7 +1317,8 @@ impl<T, const N: usize> [MaybeUninit<T>; N] {
/// let data: MaybeUninit<[u8; 1000]> = data.transpose();
/// ```
#[unstable(feature = "maybe_uninit_uninit_array_transpose", issue = "96097")]
pub fn transpose(self) -> MaybeUninit<[T; N]> {
#[inline]
pub const fn transpose(self) -> MaybeUninit<[T; N]> {
// SAFETY: T and MaybeUninit<T> have the same layout
unsafe { super::transmute_copy(&ManuallyDrop::new(self)) }
}
2 changes: 1 addition & 1 deletion src/test/ui/async-await/no-const-async.stderr
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ note: ...which requires borrow-checking `x`...
|
LL | pub const async fn x() {}
| ^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `x`...
note: ...which requires processing MIR for `x`...
--> $DIR/no-const-async.rs:4:1
|
LL | pub const async fn x() {}
2 changes: 1 addition & 1 deletion src/test/ui/binop/issue-77910-1.stderr
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ LL | assert_eq!(foo, y);
| ^^^^^^^^^^^^^^^^^^ `for<'a> fn(&'a i32) -> &'a i32 {foo}` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= help: the trait `Debug` is not implemented for fn item `for<'a> fn(&'a i32) -> &'a i32 {foo}`
= help: use parentheses to call the function: `foo(s)`
= help: use parentheses to call this function: `foo(/* &i32 */)`
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 2 previous errors
4 changes: 4 additions & 0 deletions src/test/ui/closures/closure-bounds-subtype.stderr
Original file line number Diff line number Diff line change
@@ -11,6 +11,10 @@ note: required by a bound in `take_const_owned`
|
LL | fn take_const_owned<F>(_: F) where F: FnOnce() + Sync + Send {
| ^^^^ required by this bound in `take_const_owned`
help: use parentheses to call this type parameter
|
LL | take_const_owned(f());
| ++
help: consider further restricting this bound
|
LL | fn give_owned<F>(f: F) where F: FnOnce() + Send + std::marker::Sync {
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0391]: cycle detected when building an abstract representation for test::{constant#0}
error[E0391]: cycle detected when building an abstract representation for `test::{constant#0}`
--> $DIR/closures.rs:3:35
|
LL | fn test<const N: usize>() -> [u8; N + (|| 42)()] {}
@@ -14,7 +14,7 @@ note: ...which requires type-checking `test::{constant#0}`...
|
LL | fn test<const N: usize>() -> [u8; N + (|| 42)()] {}
| ^^^^^^^^^^^^^
= note: ...which again requires building an abstract representation for test::{constant#0}, completing the cycle
= note: ...which again requires building an abstract representation for `test::{constant#0}`, completing the cycle
note: cycle used when checking that `test` is well-formed
--> $DIR/closures.rs:3:1
|
4 changes: 2 additions & 2 deletions src/test/ui/drop/drop_order.rs
Original file line number Diff line number Diff line change
@@ -129,10 +129,10 @@ impl DropOrderCollector {
// take the "else" branch
if self.option_loud_drop(6).is_some() // 2
&& self.option_loud_drop(5).is_some() // 1
&& let None = self.option_loud_drop(7) { // 3
&& let None = self.option_loud_drop(8) { // 4
unreachable!();
} else {
self.print(8); // 4
self.print(7); // 3
}

// let exprs interspersed
12 changes: 12 additions & 0 deletions src/test/ui/drop/issue-100276.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// check-pass
// compile-flags: -Z validate-mir
#![feature(let_chains)]

fn let_chains(entry: std::io::Result<std::fs::DirEntry>) {
if let Ok(entry) = entry
&& let Some(s) = entry.file_name().to_str()
&& s.contains("")
{}
}

fn main() {}
8 changes: 4 additions & 4 deletions src/test/ui/impl-trait/auto-trait-leak.stderr
Original file line number Diff line number Diff line change
@@ -9,12 +9,12 @@ note: ...which requires borrow-checking `cycle1`...
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `cycle1`...
note: ...which requires processing MIR for `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing MIR for `cycle1`...
note: ...which requires preparing `cycle1` for borrow checking...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
@@ -50,12 +50,12 @@ note: ...which requires borrow-checking `cycle2`...
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `cycle2`...
note: ...which requires processing MIR for `cycle2`...
--> $DIR/auto-trait-leak.rs:19:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing MIR for `cycle2`...
note: ...which requires preparing `cycle2` for borrow checking...
--> $DIR/auto-trait-leak.rs:19:1
|
LL | fn cycle2() -> impl Clone {
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-35241.stderr
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ LL | fn test() -> Foo { Foo }
|
= note: expected struct `Foo`
found fn item `fn(u32) -> Foo {Foo}`
help: use parentheses to instantiate this tuple struct
help: use parentheses to construct this tuple struct
|
LL | fn test() -> Foo { Foo(/* u32 */) }
| +++++++++++
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@ LL | assert_eq!(a, 0);
| ^^^^^^^^^^^^^^^^ `fn() -> i32 {a}` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= help: the trait `Debug` is not implemented for fn item `fn() -> i32 {a}`
= help: use parentheses to call the function: `a()`
= help: use parentheses to call this function: `a()`
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 3 previous errors
11 changes: 11 additions & 0 deletions src/test/ui/lifetimes/elided-lifetime-in-param-pat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// check-pass

struct S<T> {
_t: T,
}

fn f(S::<&i8> { .. }: S<&i8>) {}

fn main() {
f(S { _t: &42_i8 });
}
8 changes: 4 additions & 4 deletions src/test/ui/mir/mir_let_chains_drop_order.rs
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ use std::panic;
pub struct DropLogger<'a, T> {
extra: T,
id: usize,
log: &'a panic::AssertUnwindSafe<RefCell<Vec<usize>>>
log: &'a panic::AssertUnwindSafe<RefCell<Vec<usize>>>,
}

impl<'a, T> Drop for DropLogger<'a, T> {
@@ -55,9 +55,9 @@ fn main() {
else {
// 10 is not constructed
d(10, None)
}
},
);
assert_eq!(get(), vec![3, 8, 7, 1, 2]);
assert_eq!(get(), vec![8, 7, 1, 3, 2]);
}
assert_eq!(get(), vec![0, 4, 6, 9, 5]);

@@ -89,5 +89,5 @@ fn main() {
panic::panic_any(InjectedFailure)
);
});
assert_eq!(get(), vec![14, 19, 20, 17, 15, 11, 18, 16, 12, 13]);
assert_eq!(get(), vec![20, 17, 15, 11, 19, 18, 16, 12, 14, 13]);
}
6 changes: 3 additions & 3 deletions src/test/ui/parser/fn-header-semantic-fail.stderr
Original file line number Diff line number Diff line change
@@ -199,7 +199,7 @@ note: ...which requires borrow-checking `main::ff5`...
|
LL | const async unsafe extern "C" fn ff5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `main::ff5`...
note: ...which requires processing MIR for `main::ff5`...
--> $DIR/fn-header-semantic-fail.rs:12:5
|
LL | const async unsafe extern "C" fn ff5() {}
@@ -235,7 +235,7 @@ note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
note: ...which requires processing MIR for `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
--> $DIR/fn-header-semantic-fail.rs:33:9
|
LL | const async unsafe extern "C" fn ft5() {}
@@ -271,7 +271,7 @@ note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-
|
LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5`...
note: ...which requires processing MIR for `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5`...
--> $DIR/fn-header-semantic-fail.rs:45:9
|
LL | const async unsafe extern "C" fn fi5() {}
6 changes: 3 additions & 3 deletions src/test/ui/resolve/privacy-enum-ctor.stderr
Original file line number Diff line number Diff line change
@@ -327,7 +327,7 @@ LL | let _: Z = Z::Fn;
|
= note: expected enum `Z`
found fn item `fn(u8) -> Z {Z::Fn}`
help: use parentheses to instantiate this tuple variant
help: use parentheses to construct this tuple variant
|
LL | let _: Z = Z::Fn(/* u8 */);
| ++++++++++
@@ -362,7 +362,7 @@ LL | let _: E = m::E::Fn;
|
= note: expected enum `E`
found fn item `fn(u8) -> E {E::Fn}`
help: use parentheses to instantiate this tuple variant
help: use parentheses to construct this tuple variant
|
LL | let _: E = m::E::Fn(/* u8 */);
| ++++++++++
@@ -397,7 +397,7 @@ LL | let _: E = E::Fn;
|
= note: expected enum `E`
found fn item `fn(u8) -> E {E::Fn}`
help: use parentheses to instantiate this tuple variant
help: use parentheses to construct this tuple variant
|
LL | let _: E = E::Fn(/* u8 */);
| ++++++++++
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
error[E0277]: `fn() -> impl Future<Output = ()> {foo}` is not a future
--> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:10:9
|
LL | async fn foo() {}
| --- consider calling this function
...
LL | bar(foo);
| --- ^^^ `fn() -> impl Future<Output = ()> {foo}` is not a future
| |
@@ -16,16 +13,14 @@ note: required by a bound in `bar`
|
LL | fn bar(f: impl Future<Output=()>) {}
| ^^^^^^^^^^^^^^^^^ required by this bound in `bar`
help: use parentheses to call the function
help: use parentheses to call this function
|
LL | bar(foo());
| ++

error[E0277]: `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33]` is not a future
--> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:12:9
|
LL | let async_closure = async || ();
| -------- consider calling this closure
LL | bar(async_closure);
| --- ^^^^^^^^^^^^^ `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33]` is not a future
| |
@@ -38,7 +33,7 @@ note: required by a bound in `bar`
|
LL | fn bar(f: impl Future<Output=()>) {}
| ^^^^^^^^^^^^^^^^^ required by this bound in `bar`
help: use parentheses to call the closure
help: use parentheses to call this closure
|
LL | bar(async_closure());
| ++
17 changes: 17 additions & 0 deletions src/test/ui/suggestions/call-on-unimplemented-ctor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
fn main() {
insert_resource(Marker);
insert_resource(Time);
//~^ ERROR the trait bound `fn(u32) -> Time {Time}: Resource` is not satisfied
//~| HELP use parentheses to construct this tuple struct
}

trait Resource {}

fn insert_resource<R: Resource>(resource: R) {}

struct Marker;
impl Resource for Marker {}

struct Time(u32);

impl Resource for Time {}
21 changes: 21 additions & 0 deletions src/test/ui/suggestions/call-on-unimplemented-ctor.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0277]: the trait bound `fn(u32) -> Time {Time}: Resource` is not satisfied
--> $DIR/call-on-unimplemented-ctor.rs:3:21
|
LL | insert_resource(Time);
| --------------- ^^^^ the trait `Resource` is not implemented for fn item `fn(u32) -> Time {Time}`
| |
| required by a bound introduced by this call
|
note: required by a bound in `insert_resource`
--> $DIR/call-on-unimplemented-ctor.rs:10:23
|
LL | fn insert_resource<R: Resource>(resource: R) {}
| ^^^^^^^^ required by this bound in `insert_resource`
help: use parentheses to construct this tuple struct
|
LL | insert_resource(Time(/* u32 */));
| +++++++++++

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
15 changes: 15 additions & 0 deletions src/test/ui/suggestions/call-on-unimplemented-fn-ptr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
struct Foo;

trait Bar {}

impl Bar for Foo {}

fn needs_bar<T: Bar>(_: T) {}

fn blah(f: fn() -> Foo) {
needs_bar(f);
//~^ ERROR the trait bound `fn() -> Foo: Bar` is not satisfied
//~| HELP use parentheses to call this function pointer
}

fn main() {}
21 changes: 21 additions & 0 deletions src/test/ui/suggestions/call-on-unimplemented-fn-ptr.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0277]: the trait bound `fn() -> Foo: Bar` is not satisfied
--> $DIR/call-on-unimplemented-fn-ptr.rs:10:15
|
LL | needs_bar(f);
| --------- ^ the trait `Bar` is not implemented for `fn() -> Foo`
| |
| required by a bound introduced by this call
|
note: required by a bound in `needs_bar`
--> $DIR/call-on-unimplemented-fn-ptr.rs:7:17
|
LL | fn needs_bar<T: Bar>(_: T) {}
| ^^^ required by this bound in `needs_bar`
help: use parentheses to call this function pointer
|
LL | needs_bar(f());
| ++

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
error[E0277]: the trait bound `fn() -> impl T<O = ()> {foo}: T` is not satisfied
--> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:17:9
|
LL | fn foo() -> impl T<O=()> { S }
| --- consider calling this function
...
LL | bar(foo);
| --- ^^^ the trait `T` is not implemented for fn item `fn() -> impl T<O = ()> {foo}`
| |
@@ -14,16 +11,14 @@ note: required by a bound in `bar`
|
LL | fn bar(f: impl T<O=()>) {}
| ^^^^^^^ required by this bound in `bar`
help: use parentheses to call the function
help: use parentheses to call this function
|
LL | bar(foo());
| ++

error[E0277]: the trait bound `[closure@$DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:18:19: 18:21]: T` is not satisfied
--> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:19:9
|
LL | let closure = || S;
| -- consider calling this closure
LL | bar(closure);
| --- ^^^^^^^ the trait `T` is not implemented for closure `[closure@$DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:18:19: 18:21]`
| |
@@ -34,7 +29,7 @@ note: required by a bound in `bar`
|
LL | fn bar(f: impl T<O=()>) {}
| ^^^^^^^ required by this bound in `bar`
help: use parentheses to call the closure
help: use parentheses to call this closure
|
LL | bar(closure());
| ++
Original file line number Diff line number Diff line change
@@ -49,7 +49,7 @@ LL | let _: S = S;
|
= note: expected struct `S`
found fn item `fn(usize, usize) -> S {S}`
help: use parentheses to instantiate this tuple struct
help: use parentheses to construct this tuple struct
|
LL | let _: S = S(/* usize */, /* usize */);
| ++++++++++++++++++++++++++
@@ -85,7 +85,7 @@ LL | let _: V = V;
|
= note: expected struct `V`
found fn item `fn() -> V {V}`
help: use parentheses to instantiate this tuple struct
help: use parentheses to construct this tuple struct
|
LL | let _: V = V();
| ++
@@ -139,7 +139,7 @@ LL | let _: E = E::A;
|
= note: expected enum `E`
found fn item `fn(usize) -> E {E::A}`
help: use parentheses to instantiate this tuple variant
help: use parentheses to construct this tuple variant
|
LL | let _: E = E::A(/* usize */);
| +++++++++++++
2 changes: 1 addition & 1 deletion src/test/ui/treat-err-as-bug/delay_span_bug.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// compile-flags: -Ztreat-err-as-bug
// failure-status: 101
// error-pattern: aborting due to `-Z treat-err-as-bug=1`
// error-pattern: [trigger_delay_span_bug] trigger a delay span bug
// error-pattern: [trigger_delay_span_bug] triggering a delay span bug
// normalize-stderr-test "note: .*\n\n" -> ""
// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
// rustc-env:RUST_BACKTRACE=0
2 changes: 1 addition & 1 deletion src/test/ui/treat-err-as-bug/delay_span_bug.stderr
Original file line number Diff line number Diff line change
@@ -7,5 +7,5 @@ LL | fn main() {}
error: internal compiler error: unexpected panic

query stack during panic:
#0 [trigger_delay_span_bug] trigger a delay span bug
#0 [trigger_delay_span_bug] triggering a delay span bug
end of query stack
2 changes: 1 addition & 1 deletion src/test/ui/typeck/issue-87181/empty-tuple-method.stderr
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ error[E0599]: no method named `foo` found for fn item `fn() -> Foo {Foo}` in the
LL | thing.bar.foo();
| ^^^ method not found in `fn() -> Foo {Foo}`
|
help: use parentheses to instantiate this tuple struct
help: use parentheses to construct this tuple struct
|
LL | (thing.bar)().foo();
| + +++
2 changes: 1 addition & 1 deletion src/test/ui/typeck/issue-87181/enum-variant.stderr
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ error[E0599]: no method named `foo` found for fn item `fn() -> Foo {Foo::Tup}` i
LL | thing.bar.foo();
| ^^^ method not found in `fn() -> Foo {Foo::Tup}`
|
help: use parentheses to instantiate this tuple variant
help: use parentheses to construct this tuple variant
|
LL | (thing.bar)().foo();
| + +++
2 changes: 1 addition & 1 deletion src/test/ui/typeck/issue-87181/tuple-field.stderr
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ error[E0609]: no field `0` on type `fn(char, u16) -> Foo {Foo}`
LL | thing.bar.0;
| ^
|
help: use parentheses to instantiate this tuple struct
help: use parentheses to construct this tuple struct
|
LL | (thing.bar)(/* char */, /* u16 */).0;
| + ++++++++++++++++++++++++