Auto merge of #107106 - matthiaskrgr:rollup-g7r1ep0, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #106699 ([drop tracking] Visit break expressions ) - #106738 (Fix known-bug annotations) - #106891 (Tweak "borrow closure argument" suggestion) - #106928 (add raw identifier for keyword in suggestion) - #107065 (Clippy: Make sure to include in beta: Move `unchecked_duration_subtraction` to pedantic) - #107068 (autoderive Subdiagnostic for AddtoExternBlockSuggestion) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
a6269dad38
@ -1100,16 +1100,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
extern_block_suggestion: match sig.header.ext {
|
||||
Extern::None => None,
|
||||
Extern::Implicit(start_span) => Some(ExternBlockSuggestion {
|
||||
Extern::Implicit(start_span) => Some(ExternBlockSuggestion::Implicit {
|
||||
start_span,
|
||||
end_span: item.span.shrink_to_hi(),
|
||||
abi: None,
|
||||
}),
|
||||
Extern::Explicit(abi, start_span) => Some(ExternBlockSuggestion {
|
||||
start_span,
|
||||
end_span: item.span.shrink_to_hi(),
|
||||
abi: Some(abi.symbol_unescaped),
|
||||
}),
|
||||
Extern::Explicit(abi, start_span) => {
|
||||
Some(ExternBlockSuggestion::Explicit {
|
||||
start_span,
|
||||
end_span: item.span.shrink_to_hi(),
|
||||
abi: abi.symbol_unescaped,
|
||||
})
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
//! Errors emitted by ast_passes.
|
||||
|
||||
use rustc_errors::{fluent, AddToDiagnostic, Applicability, Diagnostic, SubdiagnosticMessage};
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
@ -207,28 +206,21 @@ pub struct FnWithoutBody {
|
||||
pub extern_block_suggestion: Option<ExternBlockSuggestion>,
|
||||
}
|
||||
|
||||
pub struct ExternBlockSuggestion {
|
||||
pub start_span: Span,
|
||||
pub end_span: Span,
|
||||
pub abi: Option<Symbol>,
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for ExternBlockSuggestion {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
||||
{
|
||||
let start_suggestion = if let Some(abi) = self.abi {
|
||||
format!("extern \"{}\" {{", abi)
|
||||
} else {
|
||||
"extern {".to_owned()
|
||||
};
|
||||
let end_suggestion = " }".to_owned();
|
||||
|
||||
diag.multipart_suggestion(
|
||||
fluent::extern_block_suggestion,
|
||||
vec![(self.start_span, start_suggestion), (self.end_span, end_suggestion)],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum ExternBlockSuggestion {
|
||||
#[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")]
|
||||
Implicit {
|
||||
#[suggestion_part(code = "extern {{")]
|
||||
start_span: Span,
|
||||
#[suggestion_part(code = " }}")]
|
||||
end_span: Span,
|
||||
},
|
||||
#[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")]
|
||||
Explicit {
|
||||
#[suggestion_part(code = "extern \"{abi}\" {{")]
|
||||
start_span: Span,
|
||||
#[suggestion_part(code = " }}")]
|
||||
end_span: Span,
|
||||
abi: Symbol,
|
||||
},
|
||||
}
|
||||
|
@ -88,4 +88,5 @@ ast_passes_ty_alias_without_body =
|
||||
ast_passes_fn_without_body =
|
||||
free function without a body
|
||||
.suggestion = provide a definition for the function
|
||||
.extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block
|
||||
|
||||
ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block
|
||||
|
@ -304,8 +304,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
|
||||
let mut reinit = None;
|
||||
match expr.kind {
|
||||
ExprKind::Assign(lhs, rhs, _) => {
|
||||
self.visit_expr(lhs);
|
||||
self.visit_expr(rhs);
|
||||
self.visit_expr(lhs);
|
||||
|
||||
reinit = Some(lhs);
|
||||
}
|
||||
@ -433,7 +433,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
|
||||
self.drop_ranges.add_control_edge(self.expr_index, *target)
|
||||
}),
|
||||
|
||||
ExprKind::Break(destination, ..) => {
|
||||
ExprKind::Break(destination, value) => {
|
||||
// destination either points to an expression or to a block. We use
|
||||
// find_target_expression_from_destination to use the last expression of the block
|
||||
// if destination points to a block.
|
||||
@ -443,7 +443,11 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
|
||||
// will refer to the end of the block due to the post order traversal.
|
||||
self.find_target_expression_from_destination(destination).map_or((), |target| {
|
||||
self.drop_ranges.add_control_edge_hir_id(self.expr_index, target)
|
||||
})
|
||||
});
|
||||
|
||||
if let Some(value) = value {
|
||||
self.visit_expr(value);
|
||||
}
|
||||
}
|
||||
|
||||
ExprKind::Call(f, args) => {
|
||||
@ -465,6 +469,12 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
|
||||
|
||||
ExprKind::AddrOf(..)
|
||||
| ExprKind::Array(..)
|
||||
// FIXME(eholk): We probably need special handling for AssignOps. The ScopeTree builder
|
||||
// in region.rs runs both lhs then rhs and rhs then lhs and then sets all yields to be
|
||||
// the latest they show up in either traversal. With the older scope-based
|
||||
// approximation, this was fine, but it's probably not right now. What we probably want
|
||||
// to do instead is still run both orders, but consider anything that showed up as a
|
||||
// yield in either order.
|
||||
| ExprKind::AssignOp(..)
|
||||
| ExprKind::Binary(..)
|
||||
| ExprKind::Block(..)
|
||||
@ -502,6 +512,9 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
|
||||
|
||||
// Increment expr_count here to match what InteriorVisitor expects.
|
||||
self.expr_index = self.expr_index + 1;
|
||||
|
||||
// Save a node mapping to get better CFG visualization
|
||||
self.drop_ranges.add_node_mapping(pat.hir_id, self.expr_index);
|
||||
}
|
||||
}
|
||||
|
||||
@ -521,7 +534,7 @@ impl DropRangesBuilder {
|
||||
}
|
||||
});
|
||||
}
|
||||
debug!("hir_id_map: {:?}", tracked_value_map);
|
||||
debug!("hir_id_map: {:#?}", tracked_value_map);
|
||||
let num_values = tracked_value_map.len();
|
||||
Self {
|
||||
tracked_value_map,
|
||||
|
@ -2,6 +2,7 @@
|
||||
//! flow graph when needed for debugging.
|
||||
|
||||
use rustc_graphviz as dot;
|
||||
use rustc_hir::{Expr, ExprKind, Node};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
use super::{DropRangesBuilder, PostOrderId};
|
||||
@ -80,10 +81,14 @@ impl<'a> dot::Labeller<'a> for DropRangesGraph<'_, '_> {
|
||||
.post_order_map
|
||||
.iter()
|
||||
.find(|(_hir_id, &post_order_id)| post_order_id == *n)
|
||||
.map_or("<unknown>".into(), |(hir_id, _)| self
|
||||
.tcx
|
||||
.hir()
|
||||
.node_to_string(*hir_id))
|
||||
.map_or("<unknown>".into(), |(hir_id, _)| format!(
|
||||
"{}{}",
|
||||
self.tcx.hir().node_to_string(*hir_id),
|
||||
match self.tcx.hir().find(*hir_id) {
|
||||
Some(Node::Expr(Expr { kind: ExprKind::Yield(..), .. })) => " (yield)",
|
||||
_ => "",
|
||||
}
|
||||
))
|
||||
)
|
||||
.into(),
|
||||
)
|
||||
|
@ -71,10 +71,8 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
|
||||
yield_data.expr_and_pat_count, self.expr_count, source_span
|
||||
);
|
||||
|
||||
if self.fcx.sess().opts.unstable_opts.drop_tracking
|
||||
&& self
|
||||
.drop_ranges
|
||||
.is_dropped_at(hir_id, yield_data.expr_and_pat_count)
|
||||
if self
|
||||
.is_dropped_at_yield_location(hir_id, yield_data.expr_and_pat_count)
|
||||
{
|
||||
debug!("value is dropped at yield point; not recording");
|
||||
return false;
|
||||
@ -173,6 +171,18 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// If drop tracking is enabled, consult drop_ranges to see if a value is
|
||||
/// known to be dropped at a yield point and therefore can be omitted from
|
||||
/// the generator witness.
|
||||
fn is_dropped_at_yield_location(&self, value_hir_id: HirId, yield_location: usize) -> bool {
|
||||
// short-circuit if drop tracking is not enabled.
|
||||
if !self.fcx.sess().opts.unstable_opts.drop_tracking {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.drop_ranges.is_dropped_at(value_hir_id, yield_location)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_interior<'a, 'tcx>(
|
||||
|
@ -393,7 +393,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||
match self.tcx().trimmed_def_paths(()).get(&def_id) {
|
||||
None => Ok((self, false)),
|
||||
Some(symbol) => {
|
||||
self.write_str(symbol.as_str())?;
|
||||
write!(self, "{}", Ident::with_dummy_span(*symbol))?;
|
||||
Ok((self, true))
|
||||
}
|
||||
}
|
||||
|
@ -1350,6 +1350,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
expected_trait_ref,
|
||||
obligation.cause.code(),
|
||||
found_node,
|
||||
obligation.param_env,
|
||||
)
|
||||
} else {
|
||||
let (closure_span, closure_arg_span, found) = found_did
|
||||
|
@ -283,6 +283,7 @@ pub trait TypeErrCtxtExt<'tcx> {
|
||||
expected: ty::PolyTraitRef<'tcx>,
|
||||
cause: &ObligationCauseCode<'tcx>,
|
||||
found_node: Option<Node<'_>>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;
|
||||
|
||||
fn note_conflicting_closure_bounds(
|
||||
@ -1978,6 +1979,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
expected: ty::PolyTraitRef<'tcx>,
|
||||
cause: &ObligationCauseCode<'tcx>,
|
||||
found_node: Option<Node<'_>>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
pub(crate) fn build_fn_sig_ty<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
@ -2040,7 +2042,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
self.note_conflicting_closure_bounds(cause, &mut err);
|
||||
|
||||
if let Some(found_node) = found_node {
|
||||
hint_missing_borrow(span, found, expected, found_node, &mut err);
|
||||
hint_missing_borrow(self, param_env, span, found, expected, found_node, &mut err);
|
||||
}
|
||||
|
||||
err
|
||||
@ -3747,6 +3749,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
|
||||
/// Add a hint to add a missing borrow or remove an unnecessary one.
|
||||
fn hint_missing_borrow<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
span: Span,
|
||||
found: Ty<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
@ -3769,7 +3773,7 @@ fn hint_missing_borrow<'tcx>(
|
||||
// This could be a variant constructor, for example.
|
||||
let Some(fn_decl) = found_node.fn_decl() else { return; };
|
||||
|
||||
let arg_spans = fn_decl.inputs.iter().map(|ty| ty.span);
|
||||
let args = fn_decl.inputs.iter().map(|ty| ty);
|
||||
|
||||
fn get_deref_type_and_refs(mut ty: Ty<'_>) -> (Ty<'_>, usize) {
|
||||
let mut refs = 0;
|
||||
@ -3785,21 +3789,34 @@ fn hint_missing_borrow<'tcx>(
|
||||
let mut to_borrow = Vec::new();
|
||||
let mut remove_borrow = Vec::new();
|
||||
|
||||
for ((found_arg, expected_arg), arg_span) in found_args.zip(expected_args).zip(arg_spans) {
|
||||
for ((found_arg, expected_arg), arg) in found_args.zip(expected_args).zip(args) {
|
||||
let (found_ty, found_refs) = get_deref_type_and_refs(*found_arg);
|
||||
let (expected_ty, expected_refs) = get_deref_type_and_refs(*expected_arg);
|
||||
|
||||
if found_ty == expected_ty {
|
||||
if infcx.can_eq(param_env, found_ty, expected_ty).is_ok() {
|
||||
if found_refs < expected_refs {
|
||||
to_borrow.push((arg_span, expected_arg.to_string()));
|
||||
to_borrow.push((arg.span.shrink_to_lo(), "&".repeat(expected_refs - found_refs)));
|
||||
} else if found_refs > expected_refs {
|
||||
remove_borrow.push((arg_span, expected_arg.to_string()));
|
||||
let mut span = arg.span.shrink_to_lo();
|
||||
let mut left = found_refs - expected_refs;
|
||||
let mut ty = arg;
|
||||
while let hir::TyKind::Ref(_, mut_ty) = &ty.kind && left > 0 {
|
||||
span = span.with_hi(mut_ty.ty.span.lo());
|
||||
ty = mut_ty.ty;
|
||||
left -= 1;
|
||||
}
|
||||
let sugg = if left == 0 {
|
||||
(span, String::new())
|
||||
} else {
|
||||
(arg.span, expected_arg.to_string())
|
||||
};
|
||||
remove_borrow.push(sugg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !to_borrow.is_empty() {
|
||||
err.multipart_suggestion(
|
||||
err.multipart_suggestion_verbose(
|
||||
"consider borrowing the argument",
|
||||
to_borrow,
|
||||
Applicability::MaybeIncorrect,
|
||||
@ -3807,7 +3824,7 @@ fn hint_missing_borrow<'tcx>(
|
||||
}
|
||||
|
||||
if !remove_borrow.is_empty() {
|
||||
err.multipart_suggestion(
|
||||
err.multipart_suggestion_verbose(
|
||||
"do not borrow the argument",
|
||||
remove_borrow,
|
||||
Applicability::MaybeIncorrect,
|
||||
|
@ -61,7 +61,7 @@ declare_clippy_lint! {
|
||||
/// [`Instant::now()`]: std::time::Instant::now;
|
||||
#[clippy::version = "1.65.0"]
|
||||
pub UNCHECKED_DURATION_SUBTRACTION,
|
||||
suspicious,
|
||||
pedantic,
|
||||
"finds unchecked subtraction of a 'Duration' from an 'Instant'"
|
||||
}
|
||||
|
||||
|
@ -426,10 +426,15 @@ impl TestProps {
|
||||
self.known_bug = true;
|
||||
} else {
|
||||
panic!(
|
||||
"Invalid known-bug value: {known_bug}\nIt requires comma-separated issue references (`#000` or `chalk#000`) or `unknown`."
|
||||
"Invalid known-bug value: {known_bug}\nIt requires comma-separated issue references (`#000` or `chalk#000`) or `known-bug: unknown`."
|
||||
);
|
||||
}
|
||||
} else if config.parse_name_directive(ln, KNOWN_BUG) {
|
||||
panic!(
|
||||
"Invalid known-bug attribute, requires comma-separated issue references (`#000` or `chalk#000`) or `known-bug: unknown`."
|
||||
);
|
||||
}
|
||||
|
||||
config.set_name_value_directive(ln, MIR_UNIT_TEST, &mut self.mir_unit_test, |s| {
|
||||
s.trim().to_string()
|
||||
});
|
||||
|
@ -16,7 +16,7 @@ LL | fn f1<F>(_: F) where F: Fn(&(), &()) {}
|
||||
help: consider borrowing the argument
|
||||
|
|
||||
LL | f1(|_: &(), _: &()| {});
|
||||
| ~~~ ~~~
|
||||
| + +
|
||||
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/anonymous-higher-ranked-lifetime.rs:3:5
|
||||
@ -35,8 +35,8 @@ LL | fn f2<F>(_: F) where F: for<'a> Fn(&'a (), &()) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `f2`
|
||||
help: consider borrowing the argument
|
||||
|
|
||||
LL | f2(|_: &'a (), _: &()| {});
|
||||
| ~~~~~~ ~~~
|
||||
LL | f2(|_: &(), _: &()| {});
|
||||
| + +
|
||||
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/anonymous-higher-ranked-lifetime.rs:4:5
|
||||
@ -56,7 +56,7 @@ LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {}
|
||||
help: consider borrowing the argument
|
||||
|
|
||||
LL | f3(|_: &(), _: &()| {});
|
||||
| ~~~ ~~~
|
||||
| + +
|
||||
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/anonymous-higher-ranked-lifetime.rs:5:5
|
||||
@ -75,8 +75,8 @@ LL | fn f4<F>(_: F) where F: for<'r> Fn(&(), &'r ()) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `f4`
|
||||
help: consider borrowing the argument
|
||||
|
|
||||
LL | f4(|_: &(), _: &'r ()| {});
|
||||
| ~~~ ~~~~~~
|
||||
LL | f4(|_: &(), _: &()| {});
|
||||
| + +
|
||||
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/anonymous-higher-ranked-lifetime.rs:6:5
|
||||
@ -95,17 +95,15 @@ LL | fn f5<F>(_: F) where F: for<'r> Fn(&'r (), &'r ()) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `f5`
|
||||
help: consider borrowing the argument
|
||||
|
|
||||
LL | f5(|_: &'r (), _: &'r ()| {});
|
||||
| ~~~~~~ ~~~~~~
|
||||
LL | f5(|_: &(), _: &()| {});
|
||||
| + +
|
||||
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/anonymous-higher-ranked-lifetime.rs:7:5
|
||||
|
|
||||
LL | g1(|_: (), _: ()| {});
|
||||
| ^^ --------------
|
||||
| | | |
|
||||
| | | help: consider borrowing the argument: `&()`
|
||||
| | found signature defined here
|
||||
| ^^ -------------- found signature defined here
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected closure signature `for<'a> fn(&'a (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>) -> _`
|
||||
@ -115,15 +113,17 @@ note: required by a bound in `g1`
|
||||
|
|
||||
LL | fn g1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `g1`
|
||||
help: consider borrowing the argument
|
||||
|
|
||||
LL | g1(|_: &(), _: ()| {});
|
||||
| +
|
||||
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
|
||||
|
|
||||
LL | g2(|_: (), _: ()| {});
|
||||
| ^^ --------------
|
||||
| | | |
|
||||
| | | help: consider borrowing the argument: `&()`
|
||||
| | found signature defined here
|
||||
| ^^ -------------- found signature defined here
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected closure signature `for<'a> fn(&'a (), for<'a> fn(&'a ())) -> _`
|
||||
@ -133,15 +133,17 @@ note: required by a bound in `g2`
|
||||
|
|
||||
LL | fn g2<F>(_: F) where F: Fn(&(), fn(&())) {}
|
||||
| ^^^^^^^^^^^^^^^^ required by this bound in `g2`
|
||||
help: consider borrowing the argument
|
||||
|
|
||||
LL | g2(|_: &(), _: ()| {});
|
||||
| +
|
||||
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/anonymous-higher-ranked-lifetime.rs:9:5
|
||||
|
|
||||
LL | g3(|_: (), _: ()| {});
|
||||
| ^^ --------------
|
||||
| | | |
|
||||
| | | help: consider borrowing the argument: `&'s ()`
|
||||
| | found signature defined here
|
||||
| ^^ -------------- found signature defined here
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected closure signature `for<'s> fn(&'s (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>) -> _`
|
||||
@ -151,15 +153,17 @@ note: required by a bound in `g3`
|
||||
|
|
||||
LL | fn g3<F>(_: F) where F: for<'s> Fn(&'s (), Box<dyn Fn(&())>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `g3`
|
||||
help: consider borrowing the argument
|
||||
|
|
||||
LL | g3(|_: &(), _: ()| {});
|
||||
| +
|
||||
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
|
||||
|
|
||||
LL | g4(|_: (), _: ()| {});
|
||||
| ^^ --------------
|
||||
| | | |
|
||||
| | | help: consider borrowing the argument: `&()`
|
||||
| | found signature defined here
|
||||
| ^^ -------------- found signature defined here
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected closure signature `for<'a> fn(&'a (), for<'r> fn(&'r ())) -> _`
|
||||
@ -169,6 +173,10 @@ note: required by a bound in `g4`
|
||||
|
|
||||
LL | fn g4<F>(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `g4`
|
||||
help: consider borrowing the argument
|
||||
|
|
||||
LL | g4(|_: &(), _: ()| {});
|
||||
| +
|
||||
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/anonymous-higher-ranked-lifetime.rs:11:5
|
||||
@ -188,7 +196,7 @@ LL | fn h1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>, &(), fn(&(), &())) {}
|
||||
help: consider borrowing the argument
|
||||
|
|
||||
LL | h1(|_: &(), _: (), _: &(), _: ()| {});
|
||||
| ~~~ ~~~
|
||||
| + +
|
||||
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
|
||||
@ -207,8 +215,8 @@ LL | fn h2<F>(_: F) where F: for<'t0> Fn(&(), Box<dyn Fn(&())>, &'t0 (), fn(&(),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `h2`
|
||||
help: consider borrowing the argument
|
||||
|
|
||||
LL | h2(|_: &(), _: (), _: &'t0 (), _: ()| {});
|
||||
| ~~~ ~~~~~~~
|
||||
LL | h2(|_: &(), _: (), _: &(), _: ()| {});
|
||||
| + +
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
|
21
tests/ui/async-await/await-sequence.rs
Normal file
21
tests/ui/async-await/await-sequence.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// edition:2021
|
||||
// compile-flags: -Z drop-tracking
|
||||
// build-pass
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn main() {
|
||||
let _ = real_main();
|
||||
}
|
||||
|
||||
async fn nop() {}
|
||||
|
||||
async fn real_main() {
|
||||
nop().await;
|
||||
nop().await;
|
||||
nop().await;
|
||||
nop().await;
|
||||
|
||||
let mut map: HashMap<(), ()> = HashMap::new();
|
||||
map.insert((), nop().await);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// check-fail
|
||||
// known-bug
|
||||
// edition:2021
|
||||
// known-bug: unknown
|
||||
// unset-rustc-env:RUST_BACKTRACE
|
||||
// compile-flags:-Z trait-solver=chalk --edition=2021
|
||||
// compile-flags:-Z trait-solver=chalk
|
||||
// error-pattern:internal compiler error
|
||||
// failure-status:101
|
||||
// normalize-stderr-test "DefId([^)]*)" -> "..."
|
||||
|
@ -2,10 +2,8 @@ error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/multiple-fn-bounds.rs:10:5
|
||||
|
|
||||
LL | foo(move |x| v);
|
||||
| ^^^ --------
|
||||
| | | |
|
||||
| | | help: do not borrow the argument: `char`
|
||||
| | found signature defined here
|
||||
| ^^^ -------- found signature defined here
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected closure signature `fn(char) -> _`
|
||||
@ -20,6 +18,10 @@ note: required by a bound in `foo`
|
||||
|
|
||||
LL | fn foo<F: Fn(&char) -> bool + Fn(char) -> bool>(f: F) {
|
||||
| ^^^^^^^^^^^^^^^^ required by this bound in `foo`
|
||||
help: do not borrow the argument
|
||||
|
|
||||
LL | foo(move |char| v);
|
||||
| ~~~~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// check-pass
|
||||
// known-bug
|
||||
// known-bug: unknown
|
||||
|
||||
// This should not compile, as the compiler should not know
|
||||
// `A - 0` is satisfied `?x - 0` if `?x` is inferred to `A`.
|
||||
@ -10,7 +10,6 @@ pub struct Ref<'a>(&'a i32);
|
||||
|
||||
impl<'a> Ref<'a> {
|
||||
pub fn foo<const A: usize>() -> [(); A - 0] {
|
||||
//~^ WARN function cannot
|
||||
Self::foo()
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ warning: function cannot return without recursing
|
||||
|
|
||||
LL | pub fn foo<const A: usize>() -> [(); A - 0] {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
|
||||
LL |
|
||||
LL | Self::foo()
|
||||
| ----------- recursive call site
|
||||
|
|
||||
|
@ -1,5 +1,5 @@
|
||||
// check-fail
|
||||
// known-bug
|
||||
// known-bug: unknown
|
||||
|
||||
// This gives us problems because `for<'a> I::Item<'a>: Debug` should mean "for
|
||||
// all 'a where I::Item<'a> is WF", but really means "for all 'a possible"
|
||||
@ -29,7 +29,6 @@ where
|
||||
|
||||
fn main() {
|
||||
let slice = &mut ();
|
||||
//~^ temporary value dropped while borrowed
|
||||
let windows = WindowsMut { slice };
|
||||
print_items::<WindowsMut<'_>>(windows);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ error[E0716]: temporary value dropped while borrowed
|
||||
|
|
||||
LL | let slice = &mut ();
|
||||
| ^^ creates a temporary value which is freed while still in use
|
||||
...
|
||||
LL | let windows = WindowsMut { slice };
|
||||
LL | print_items::<WindowsMut<'_>>(windows);
|
||||
| -------------------------------------- argument requires that borrow lasts for `'static`
|
||||
LL | }
|
||||
|
@ -1,5 +1,5 @@
|
||||
// check-fail
|
||||
// known-bug
|
||||
// known-bug: unknown
|
||||
|
||||
// This gives us problems because `for<'a> I::Item<'a>: Debug` should mean "for
|
||||
// all 'a where I::Item<'a> is WF", but really means "for all 'a possible"
|
||||
@ -16,7 +16,6 @@ where
|
||||
{
|
||||
let mut iter2 = Eat(iter, f);
|
||||
let _next = iter2.next();
|
||||
//~^ borrowed data escapes
|
||||
true
|
||||
}
|
||||
impl<I: LendingIterator> LendingIterator for &mut I {
|
||||
|
@ -1,5 +1,5 @@
|
||||
// check-fail
|
||||
// known-bug
|
||||
// known-bug: unknown
|
||||
// edition: 2021
|
||||
|
||||
// We really should accept this, but we need implied bounds between the regions
|
||||
@ -13,7 +13,6 @@ pub trait FutureIterator {
|
||||
|
||||
fn call<I: FutureIterator>() -> impl Send {
|
||||
async { // a generator checked for autotrait impl `Send`
|
||||
//~^ lifetime bound not satisfied
|
||||
let x = None::<I::Future<'_, '_>>; // a type referencing GAT
|
||||
async {}.await; // a yield point
|
||||
}
|
||||
@ -21,16 +20,13 @@ fn call<I: FutureIterator>() -> impl Send {
|
||||
|
||||
fn call2<'a, 'b, I: FutureIterator>() -> impl Send {
|
||||
async { // a generator checked for autotrait impl `Send`
|
||||
//~^ lifetime bound not satisfied
|
||||
let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
|
||||
//~^ lifetime may not live long enough
|
||||
async {}.await; // a yield point
|
||||
}
|
||||
}
|
||||
|
||||
fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send {
|
||||
async { // a generator checked for autotrait impl `Send`
|
||||
//~^ lifetime bound not satisfied
|
||||
let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
|
||||
async {}.await; // a yield point
|
||||
}
|
||||
|
@ -2,77 +2,73 @@ error: lifetime bound not satisfied
|
||||
--> $DIR/issue-100013.rs:15:5
|
||||
|
|
||||
LL | / async { // a generator checked for autotrait impl `Send`
|
||||
LL | |
|
||||
LL | | let x = None::<I::Future<'_, '_>>; // a type referencing GAT
|
||||
LL | | async {}.await; // a yield point
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
note: the lifetime defined here...
|
||||
--> $DIR/issue-100013.rs:17:38
|
||||
--> $DIR/issue-100013.rs:16:38
|
||||
|
|
||||
LL | let x = None::<I::Future<'_, '_>>; // a type referencing GAT
|
||||
| ^^
|
||||
note: ...must outlive the lifetime defined here
|
||||
--> $DIR/issue-100013.rs:17:34
|
||||
--> $DIR/issue-100013.rs:16:34
|
||||
|
|
||||
LL | let x = None::<I::Future<'_, '_>>; // a type referencing GAT
|
||||
| ^^
|
||||
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
|
||||
|
||||
error: lifetime bound not satisfied
|
||||
--> $DIR/issue-100013.rs:23:5
|
||||
--> $DIR/issue-100013.rs:22:5
|
||||
|
|
||||
LL | / async { // a generator checked for autotrait impl `Send`
|
||||
LL | |
|
||||
LL | | let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
|
||||
LL | |
|
||||
LL | | async {}.await; // a yield point
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
note: the lifetime defined here...
|
||||
--> $DIR/issue-100013.rs:22:14
|
||||
--> $DIR/issue-100013.rs:21:14
|
||||
|
|
||||
LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send {
|
||||
| ^^
|
||||
note: ...must outlive the lifetime defined here
|
||||
--> $DIR/issue-100013.rs:22:10
|
||||
--> $DIR/issue-100013.rs:21:10
|
||||
|
|
||||
LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send {
|
||||
| ^^
|
||||
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-100013.rs:25:17
|
||||
--> $DIR/issue-100013.rs:23:17
|
||||
|
|
||||
LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send {
|
||||
| -- -- lifetime `'b` defined here
|
||||
| |
|
||||
| lifetime `'a` defined here
|
||||
...
|
||||
LL | async { // a generator checked for autotrait impl `Send`
|
||||
LL | let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'b`
|
||||
|
|
||||
= help: consider adding the following bound: `'a: 'b`
|
||||
|
||||
error: lifetime bound not satisfied
|
||||
--> $DIR/issue-100013.rs:32:5
|
||||
--> $DIR/issue-100013.rs:29:5
|
||||
|
|
||||
LL | / async { // a generator checked for autotrait impl `Send`
|
||||
LL | |
|
||||
LL | | let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
|
||||
LL | | async {}.await; // a yield point
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
note: the lifetime defined here...
|
||||
--> $DIR/issue-100013.rs:31:18
|
||||
--> $DIR/issue-100013.rs:28:18
|
||||
|
|
||||
LL | fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send {
|
||||
| ^^
|
||||
note: ...must outlive the lifetime defined here
|
||||
--> $DIR/issue-100013.rs:31:10
|
||||
--> $DIR/issue-100013.rs:28:10
|
||||
|
|
||||
LL | fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send {
|
||||
| ^^
|
||||
|
@ -1,5 +1,5 @@
|
||||
// check-fail
|
||||
// known-bug
|
||||
// known-bug: unknown
|
||||
|
||||
// We almost certainly want this to pass, but
|
||||
// it's particularly difficult currently, because we need a way of specifying
|
||||
@ -22,7 +22,6 @@ pub trait FunctorExt<T>: Sized {
|
||||
|
||||
arg = self;
|
||||
ret = <Self::Base as Functor>::fmap(arg);
|
||||
//~^ type annotations needed
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
error[E0034]: multiple applicable items in scope
|
||||
--> $DIR/issue-65634-raw-ident-suggestion.rs:21:13
|
||||
--> $DIR/issue-65634-raw-ident-suggestion.rs:24:13
|
||||
|
|
||||
LL | r#fn {}.r#struct();
|
||||
| ^^^^^^^^ multiple `r#struct` found
|
||||
|
|
||||
note: candidate #1 is defined in an impl of the trait `async` for the type `fn`
|
||||
--> $DIR/issue-65634-raw-ident-suggestion.rs:4:5
|
||||
note: candidate #1 is defined in an impl of the trait `async` for the type `r#fn`
|
||||
--> $DIR/issue-65634-raw-ident-suggestion.rs:7:5
|
||||
|
|
||||
LL | fn r#struct(&self) {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
note: candidate #2 is defined in an impl of the trait `await` for the type `fn`
|
||||
--> $DIR/issue-65634-raw-ident-suggestion.rs:10:5
|
||||
note: candidate #2 is defined in an impl of the trait `await` for the type `r#fn`
|
||||
--> $DIR/issue-65634-raw-ident-suggestion.rs:13:5
|
||||
|
|
||||
LL | fn r#struct(&self) {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
@ -0,0 +1,28 @@
|
||||
error[E0034]: multiple applicable items in scope
|
||||
--> $DIR/issue-65634-raw-ident-suggestion.rs:24:13
|
||||
|
|
||||
LL | r#fn {}.r#struct();
|
||||
| ^^^^^^^^ multiple `r#struct` found
|
||||
|
|
||||
note: candidate #1 is defined in an impl of the trait `r#async` for the type `r#fn`
|
||||
--> $DIR/issue-65634-raw-ident-suggestion.rs:7:5
|
||||
|
|
||||
LL | fn r#struct(&self) {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
note: candidate #2 is defined in an impl of the trait `r#await` for the type `r#fn`
|
||||
--> $DIR/issue-65634-raw-ident-suggestion.rs:13:5
|
||||
|
|
||||
LL | fn r#struct(&self) {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
help: disambiguate the associated function for candidate #1
|
||||
|
|
||||
LL | r#async::r#struct(&r#fn {});
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
help: disambiguate the associated function for candidate #2
|
||||
|
|
||||
LL | r#await::r#struct(&r#fn {});
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0034`.
|
@ -1,3 +1,6 @@
|
||||
// revisions: edition2015 edition2018
|
||||
//[edition2018]edition:2018
|
||||
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
trait r#async {
|
||||
|
@ -0,0 +1,5 @@
|
||||
// run-rustfix
|
||||
fn main() {
|
||||
let _ = (-10..=10).find(|x: &i32| x.signum() == 0); //~ ERROR type mismatch in closure arguments
|
||||
let _ = (-10..=10).find(|x: &i32| x.signum() == 0); //~ ERROR type mismatch in closure arguments
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
// run-rustfix
|
||||
fn main() {
|
||||
let _ = (-10..=10).find(|x: i32| x.signum() == 0); //~ ERROR type mismatch in closure arguments
|
||||
let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0); //~ ERROR type mismatch in closure arguments
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/closure-arg-type-mismatch-issue-45727.rs:3:24
|
||||
|
|
||||
LL | let _ = (-10..=10).find(|x: i32| x.signum() == 0);
|
||||
| ^^^^ -------- found signature defined here
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected closure signature `for<'a> fn(&'a {integer}) -> _`
|
||||
found closure signature `fn(i32) -> _`
|
||||
note: required by a bound in `find`
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
help: consider borrowing the argument
|
||||
|
|
||||
LL | let _ = (-10..=10).find(|x: &i32| x.signum() == 0);
|
||||
| +
|
||||
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/closure-arg-type-mismatch-issue-45727.rs:4:24
|
||||
|
|
||||
LL | let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
|
||||
| ^^^^ ----------- found signature defined here
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected closure signature `for<'a> fn(&'a {integer}) -> _`
|
||||
found closure signature `for<'a, 'b, 'c> fn(&'a &'b &'c i32) -> _`
|
||||
note: required by a bound in `find`
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
help: do not borrow the argument
|
||||
|
|
||||
LL - let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
|
||||
LL + let _ = (-10..=10).find(|x: &i32| x.signum() == 0);
|
||||
|
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0631`.
|
@ -2,16 +2,18 @@ error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/closure-arg-type-mismatch.rs:3:14
|
||||
|
|
||||
LL | a.iter().map(|_: (u32, u32)| 45);
|
||||
| ^^^ ---------------
|
||||
| | | |
|
||||
| | | help: consider borrowing the argument: `&(u32, u32)`
|
||||
| | found signature defined here
|
||||
| ^^^ --------------- found signature defined here
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected closure signature `fn(&(u32, u32)) -> _`
|
||||
found closure signature `fn((u32, u32)) -> _`
|
||||
note: required by a bound in `map`
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
help: consider borrowing the argument
|
||||
|
|
||||
LL | a.iter().map(|_: &(u32, u32)| 45);
|
||||
| +
|
||||
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/closure-arg-type-mismatch.rs:4:14
|
||||
|
@ -2,16 +2,18 @@ error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/issue-36053-2.rs:7:32
|
||||
|
|
||||
LL | once::<&str>("str").fuse().filter(|a: &str| true).count();
|
||||
| ^^^^^^ ---------
|
||||
| | | |
|
||||
| | | help: consider borrowing the argument: `&&str`
|
||||
| | found signature defined here
|
||||
| ^^^^^^ --------- found signature defined here
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected closure signature `for<'a> fn(&'a &str) -> _`
|
||||
found closure signature `for<'a> fn(&'a str) -> _`
|
||||
note: required by a bound in `filter`
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
help: consider borrowing the argument
|
||||
|
|
||||
LL | once::<&str>("str").fuse().filter(|a: &&str| true).count();
|
||||
| +
|
||||
|
||||
error[E0599]: the method `count` exists for struct `Filter<Fuse<Once<&str>>, [closure@issue-36053-2.rs:7:39]>`, but its trait bounds were not satisfied
|
||||
--> $DIR/issue-36053-2.rs:7:55
|
||||
|
Loading…
x
Reference in New Issue
Block a user