Auto merge of #106616 - compiler-errors:rollup-emcj0o3, r=compiler-errors
Rollup of 8 pull requests Successful merges: - #104163 (Don't derive Debug for `OnceWith` & `RepeatWith`) - #106131 (Mention "signature" rather than "fn pointer" when impl/trait methods are incompatible) - #106363 (Structured suggestion for `&mut dyn Iterator` when possible) - #106497 (Suggest using clone when we have &T and T implemented Clone) - #106584 (Document that `Vec::from_raw_parts[_in]` must be given a pointer from the correct allocator.) - #106600 (Suppress type errors that come from private fields) - #106602 (Add goml scripts to tidy checks) - #106606 (Do not emit structured suggestion for turbofish with wrong span) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
2e677c0645
75 changed files with 594 additions and 204 deletions
|
@ -253,8 +253,8 @@ infer_trait_placeholder_mismatch = implementation of `{$trait_def_id}` is not ge
|
|||
infer_trait_impl_diff = `impl` item signature doesn't match `trait` item signature
|
||||
.found = found `{$found}`
|
||||
.expected = expected `{$expected}`
|
||||
.expected_found = expected `{$expected}`
|
||||
{" "}found `{$found}`
|
||||
.expected_found = expected signature `{$expected}`
|
||||
{" "}found signature `{$found}`
|
||||
|
||||
infer_tid_rel_help = verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
|
||||
infer_tid_consider_borrowing = consider borrowing this type parameter in the trait
|
||||
|
|
|
@ -270,8 +270,8 @@ fn compare_method_predicate_entailment<'tcx>(
|
|||
let unnormalized_impl_fty = tcx.mk_fn_ptr(ty::Binder::dummy(unnormalized_impl_sig));
|
||||
|
||||
let norm_cause = ObligationCause::misc(impl_m_span, impl_m_hir_id);
|
||||
let impl_fty = ocx.normalize(&norm_cause, param_env, unnormalized_impl_fty);
|
||||
debug!("compare_impl_method: impl_fty={:?}", impl_fty);
|
||||
let impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_impl_sig);
|
||||
debug!("compare_impl_method: impl_fty={:?}", impl_sig);
|
||||
|
||||
let trait_sig = tcx.bound_fn_sig(trait_m.def_id).subst(tcx, trait_to_placeholder_substs);
|
||||
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig);
|
||||
|
@ -294,18 +294,17 @@ fn compare_method_predicate_entailment<'tcx>(
|
|||
// type would be more appropriate. In other places we have a `Vec<Span>`
|
||||
// corresponding to their `Vec<Predicate>`, but we don't have that here.
|
||||
// Fixing this would improve the output of test `issue-83765.rs`.
|
||||
let result = ocx.sup(&cause, param_env, trait_fty, impl_fty);
|
||||
let result = ocx.sup(&cause, param_env, trait_sig, impl_sig);
|
||||
|
||||
if let Err(terr) = result {
|
||||
debug!(?terr, "sub_types failed: impl ty {:?}, trait ty {:?}", impl_fty, trait_fty);
|
||||
debug!(?impl_sig, ?trait_sig, ?terr, "sub_types failed");
|
||||
|
||||
let emitted = report_trait_method_mismatch(
|
||||
&infcx,
|
||||
cause,
|
||||
terr,
|
||||
(trait_m, trait_fty),
|
||||
(impl_m, impl_fty),
|
||||
trait_sig,
|
||||
(trait_m, trait_sig),
|
||||
(impl_m, impl_sig),
|
||||
impl_trait_ref,
|
||||
);
|
||||
return Err(emitted);
|
||||
|
@ -484,7 +483,8 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
|||
let impl_trait_ref = tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap();
|
||||
let param_env = tcx.param_env(def_id);
|
||||
|
||||
// First, check a few of the same thing as `compare_impl_method`, just so we don't ICE during substitutions later.
|
||||
// First, check a few of the same things as `compare_impl_method`,
|
||||
// just so we don't ICE during substitution later.
|
||||
compare_number_of_generics(tcx, impl_m, trait_m, tcx.hir().span_if_local(impl_m.def_id), true)?;
|
||||
compare_generic_param_kinds(tcx, impl_m, trait_m, true)?;
|
||||
check_region_bounds_on_impl_item(tcx, impl_m, trait_m, true)?;
|
||||
|
@ -577,14 +577,11 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
|||
|
||||
debug!(?trait_sig, ?impl_sig, "equating function signatures");
|
||||
|
||||
let trait_fty = tcx.mk_fn_ptr(ty::Binder::dummy(trait_sig));
|
||||
let impl_fty = tcx.mk_fn_ptr(ty::Binder::dummy(impl_sig));
|
||||
|
||||
// Unify the whole function signature. We need to do this to fully infer
|
||||
// the lifetimes of the return type, but do this after unifying just the
|
||||
// return types, since we want to avoid duplicating errors from
|
||||
// `compare_method_predicate_entailment`.
|
||||
match ocx.eq(&cause, param_env, trait_fty, impl_fty) {
|
||||
match ocx.eq(&cause, param_env, trait_sig, impl_sig) {
|
||||
Ok(()) => {}
|
||||
Err(terr) => {
|
||||
// This function gets called during `compare_method_predicate_entailment` when normalizing a
|
||||
|
@ -595,9 +592,8 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
|||
infcx,
|
||||
cause,
|
||||
terr,
|
||||
(trait_m, trait_fty),
|
||||
(impl_m, impl_fty),
|
||||
trait_sig,
|
||||
(trait_m, trait_sig),
|
||||
(impl_m, impl_sig),
|
||||
impl_trait_ref,
|
||||
);
|
||||
return Err(emitted);
|
||||
|
@ -771,9 +767,8 @@ fn report_trait_method_mismatch<'tcx>(
|
|||
infcx: &InferCtxt<'tcx>,
|
||||
mut cause: ObligationCause<'tcx>,
|
||||
terr: TypeError<'tcx>,
|
||||
(trait_m, trait_fty): (&ty::AssocItem, Ty<'tcx>),
|
||||
(impl_m, impl_fty): (&ty::AssocItem, Ty<'tcx>),
|
||||
trait_sig: ty::FnSig<'tcx>,
|
||||
(trait_m, trait_sig): (&ty::AssocItem, ty::FnSig<'tcx>),
|
||||
(impl_m, impl_sig): (&ty::AssocItem, ty::FnSig<'tcx>),
|
||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||
) -> ErrorGuaranteed {
|
||||
let tcx = infcx.tcx;
|
||||
|
@ -858,10 +853,7 @@ fn report_trait_method_mismatch<'tcx>(
|
|||
&mut diag,
|
||||
&cause,
|
||||
trait_err_span.map(|sp| (sp, "type in trait".to_owned())),
|
||||
Some(infer::ValuePairs::Terms(ExpectedFound {
|
||||
expected: trait_fty.into(),
|
||||
found: impl_fty.into(),
|
||||
})),
|
||||
Some(infer::ValuePairs::Sigs(ExpectedFound { expected: trait_sig, found: impl_sig })),
|
||||
terr,
|
||||
false,
|
||||
false,
|
||||
|
|
|
@ -57,6 +57,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|| self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty)
|
||||
|| self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected)
|
||||
|| self.suggest_copied_or_cloned(err, expr, expr_ty, expected)
|
||||
|| self.suggest_clone_for_ref(err, expr, expr_ty, expected)
|
||||
|| self.suggest_into(err, expr, expr_ty, expected)
|
||||
|| self.suggest_floating_point_literal(err, expr, expected);
|
||||
if !suggested {
|
||||
|
|
|
@ -2217,7 +2217,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None);
|
||||
return field_ty;
|
||||
}
|
||||
private_candidate = Some((adjustments, base_def.did(), field_ty));
|
||||
private_candidate = Some((adjustments, base_def.did()));
|
||||
}
|
||||
}
|
||||
ty::Tuple(tys) => {
|
||||
|
@ -2240,12 +2240,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
self.structurally_resolved_type(autoderef.span(), autoderef.final_ty(false));
|
||||
|
||||
if let Some((adjustments, did, field_ty)) = private_candidate {
|
||||
if let Some((adjustments, did)) = private_candidate {
|
||||
// (#90483) apply adjustments to avoid ExprUseVisitor from
|
||||
// creating erroneous projection.
|
||||
self.apply_adjustments(base, adjustments);
|
||||
self.ban_private_field_access(expr, base_ty, field, did);
|
||||
return field_ty;
|
||||
return self.tcx().ty_error();
|
||||
}
|
||||
|
||||
if field.name == kw::Empty {
|
||||
|
|
|
@ -1014,6 +1014,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn suggest_clone_for_ref(
|
||||
&self,
|
||||
diag: &mut Diagnostic,
|
||||
expr: &hir::Expr<'_>,
|
||||
expr_ty: Ty<'tcx>,
|
||||
expected_ty: Ty<'tcx>,
|
||||
) -> bool {
|
||||
if let ty::Ref(_, inner_ty, hir::Mutability::Not) = expr_ty.kind()
|
||||
&& let Some(clone_trait_def) = self.tcx.lang_items().clone_trait()
|
||||
&& expected_ty == *inner_ty
|
||||
&& self
|
||||
.infcx
|
||||
.type_implements_trait(
|
||||
clone_trait_def,
|
||||
[self.tcx.erase_regions(expected_ty)],
|
||||
self.param_env
|
||||
)
|
||||
.must_apply_modulo_regions()
|
||||
{
|
||||
diag.span_suggestion_verbose(
|
||||
expr.span.shrink_to_hi(),
|
||||
"consider using clone here",
|
||||
".clone()",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub(crate) fn suggest_copied_or_cloned(
|
||||
&self,
|
||||
diag: &mut Diagnostic,
|
||||
|
|
|
@ -57,7 +57,12 @@ pub enum MethodError<'tcx> {
|
|||
PrivateMatch(DefKind, DefId, Vec<DefId>),
|
||||
|
||||
// Found a `Self: Sized` bound where `Self` is a trait object.
|
||||
IllegalSizedBound(Vec<DefId>, bool, Span),
|
||||
IllegalSizedBound {
|
||||
candidates: Vec<DefId>,
|
||||
needs_mut: bool,
|
||||
bound_span: Span,
|
||||
self_expr: &'tcx hir::Expr<'tcx>,
|
||||
},
|
||||
|
||||
// Found a match, but the return type is wrong
|
||||
BadReturnType,
|
||||
|
@ -112,7 +117,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
Err(NoMatch(..)) => false,
|
||||
Err(Ambiguity(..)) => true,
|
||||
Err(PrivateMatch(..)) => allow_private,
|
||||
Err(IllegalSizedBound(..)) => true,
|
||||
Err(IllegalSizedBound { .. }) => true,
|
||||
Err(BadReturnType) => bug!("no return type expectations but got BadReturnType"),
|
||||
}
|
||||
}
|
||||
|
@ -236,7 +241,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
_ => Vec::new(),
|
||||
};
|
||||
|
||||
return Err(IllegalSizedBound(candidates, needs_mut, span));
|
||||
return Err(IllegalSizedBound { candidates, needs_mut, bound_span: span, self_expr });
|
||||
}
|
||||
|
||||
Ok(result.callee)
|
||||
|
|
|
@ -176,10 +176,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
err.emit();
|
||||
}
|
||||
|
||||
MethodError::IllegalSizedBound(candidates, needs_mut, bound_span) => {
|
||||
let msg = format!("the `{}` method cannot be invoked on a trait object", item_name);
|
||||
MethodError::IllegalSizedBound { candidates, needs_mut, bound_span, self_expr } => {
|
||||
let msg = if needs_mut {
|
||||
with_forced_trimmed_paths!(format!(
|
||||
"the `{item_name}` method cannot be invoked on `{rcvr_ty}`"
|
||||
))
|
||||
} else {
|
||||
format!("the `{item_name}` method cannot be invoked on a trait object")
|
||||
};
|
||||
let mut err = self.sess().struct_span_err(span, &msg);
|
||||
err.span_label(bound_span, "this has a `Sized` requirement");
|
||||
if !needs_mut {
|
||||
err.span_label(bound_span, "this has a `Sized` requirement");
|
||||
}
|
||||
if !candidates.is_empty() {
|
||||
let help = format!(
|
||||
"{an}other candidate{s} {were} found in the following trait{s}, perhaps \
|
||||
|
@ -197,7 +205,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
*region,
|
||||
ty::TypeAndMut { ty: *t_type, mutbl: mutability.invert() },
|
||||
);
|
||||
err.note(&format!("you need `{}` instead of `{}`", trait_type, rcvr_ty));
|
||||
let msg = format!("you need `{}` instead of `{}`", trait_type, rcvr_ty);
|
||||
let mut kind = &self_expr.kind;
|
||||
while let hir::ExprKind::AddrOf(_, _, expr)
|
||||
| hir::ExprKind::Unary(hir::UnOp::Deref, expr) = kind
|
||||
{
|
||||
kind = &expr.kind;
|
||||
}
|
||||
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = kind
|
||||
&& let hir::def::Res::Local(hir_id) = path.res
|
||||
&& let Some(hir::Node::Pat(b)) = self.tcx.hir().find(hir_id)
|
||||
&& let Some(hir::Node::Param(p)) = self.tcx.hir().find_parent(b.hir_id)
|
||||
&& let Some(node) = self.tcx.hir().find_parent(p.hir_id)
|
||||
&& let Some(decl) = node.fn_decl()
|
||||
&& let Some(ty) = decl.inputs.iter().find(|ty| ty.span == p.ty_span)
|
||||
&& let hir::TyKind::Ref(_, mut_ty) = &ty.kind
|
||||
&& let hir::Mutability::Not = mut_ty.mutbl
|
||||
{
|
||||
err.span_suggestion_verbose(
|
||||
mut_ty.ty.span.shrink_to_lo(),
|
||||
&msg,
|
||||
"mut ",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
err.help(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
|
|
|
@ -427,3 +427,15 @@ impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> {
|
||||
fn to_trace(
|
||||
_: TyCtxt<'tcx>,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
a_is_expected: bool,
|
||||
a: Self,
|
||||
b: Self,
|
||||
) -> TypeTrace<'tcx> {
|
||||
TypeTrace { cause: cause.clone(), values: Sigs(ExpectedFound::new(a_is_expected, a, b)) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1428,8 +1428,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
impl<'tcx> OpaqueTypesVisitor<'tcx> {
|
||||
fn visit_expected_found(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
expected: impl TypeVisitable<'tcx>,
|
||||
found: impl TypeVisitable<'tcx>,
|
||||
ignore_span: Span,
|
||||
) -> Self {
|
||||
let mut types_visitor = OpaqueTypesVisitor {
|
||||
|
@ -1569,6 +1569,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
_ => (false, Mismatch::Fixed("type")),
|
||||
}
|
||||
}
|
||||
ValuePairs::Sigs(infer::ExpectedFound { expected, found }) => {
|
||||
OpaqueTypesVisitor::visit_expected_found(self.tcx, expected, found, span)
|
||||
.report(diag);
|
||||
(false, Mismatch::Fixed("signature"))
|
||||
}
|
||||
ValuePairs::TraitRefs(_) | ValuePairs::PolyTraitRefs(_) => {
|
||||
(false, Mismatch::Fixed("trait"))
|
||||
}
|
||||
|
@ -2040,6 +2045,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
ret => ret,
|
||||
}
|
||||
}
|
||||
infer::Sigs(exp_found) => {
|
||||
let exp_found = self.resolve_vars_if_possible(exp_found);
|
||||
if exp_found.references_error() {
|
||||
return None;
|
||||
}
|
||||
let (exp, fnd) = self.cmp_fn_sig(
|
||||
&ty::Binder::dummy(exp_found.expected),
|
||||
&ty::Binder::dummy(exp_found.found),
|
||||
);
|
||||
Some((exp, fnd, None, None))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use crate::errors::{ConsiderBorrowingParamHelp, RelationshipHelp, TraitImplDiff};
|
||||
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
|
||||
use crate::infer::lexical_region_resolve::RegionResolutionError;
|
||||
use crate::infer::Subtype;
|
||||
use crate::infer::{Subtype, ValuePairs};
|
||||
use crate::traits::ObligationCauseCode::CompareImplItemObligation;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir as hir;
|
||||
|
@ -11,6 +11,7 @@ use rustc_hir::def::Res;
|
|||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty::error::ExpectedFound;
|
||||
use rustc_middle::ty::print::RegionHighlightMode;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor};
|
||||
use rustc_span::Span;
|
||||
|
@ -23,22 +24,27 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||
let error = self.error.as_ref()?;
|
||||
debug!("try_report_impl_not_conforming_to_trait {:?}", error);
|
||||
if let RegionResolutionError::SubSupConflict(
|
||||
_,
|
||||
var_origin,
|
||||
sub_origin,
|
||||
_sub,
|
||||
sup_origin,
|
||||
_sup,
|
||||
_,
|
||||
) = error.clone()
|
||||
_,
|
||||
var_origin,
|
||||
sub_origin,
|
||||
_sub,
|
||||
sup_origin,
|
||||
_sup,
|
||||
_,
|
||||
) = error.clone()
|
||||
&& let (Subtype(sup_trace), Subtype(sub_trace)) = (&sup_origin, &sub_origin)
|
||||
&& let sub_expected_found @ Some((sub_expected, sub_found)) = sub_trace.values.ty()
|
||||
&& let sup_expected_found @ Some(_) = sup_trace.values.ty()
|
||||
&& let CompareImplItemObligation { trait_item_def_id, .. } = sub_trace.cause.code()
|
||||
&& sup_expected_found == sub_expected_found
|
||||
&& sub_trace.values == sup_trace.values
|
||||
&& let ValuePairs::Sigs(ExpectedFound { expected, found }) = sub_trace.values
|
||||
{
|
||||
let guar =
|
||||
self.emit_err(var_origin.span(), sub_expected, sub_found, *trait_item_def_id);
|
||||
// FIXME(compiler-errors): Don't like that this needs `Ty`s, but
|
||||
// all of the region highlighting machinery only deals with those.
|
||||
let guar = self.emit_err(
|
||||
var_origin.span(),
|
||||
self.cx.tcx.mk_fn_ptr(ty::Binder::dummy(expected)),
|
||||
self.cx.tcx.mk_fn_ptr(ty::Binder::dummy(found)),
|
||||
*trait_item_def_id,
|
||||
);
|
||||
return Some(guar);
|
||||
}
|
||||
None
|
||||
|
|
|
@ -361,6 +361,7 @@ pub enum ValuePairs<'tcx> {
|
|||
Terms(ExpectedFound<ty::Term<'tcx>>),
|
||||
TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
|
||||
PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
|
||||
Sigs(ExpectedFound<ty::FnSig<'tcx>>),
|
||||
}
|
||||
|
||||
impl<'tcx> ValuePairs<'tcx> {
|
||||
|
|
|
@ -1104,7 +1104,11 @@ impl<'a> Parser<'a> {
|
|||
return if token::ModSep == self.token.kind {
|
||||
// We have some certainty that this was a bad turbofish at this point.
|
||||
// `foo< bar >::`
|
||||
err.suggest_turbofish = Some(op.span.shrink_to_lo());
|
||||
if let ExprKind::Binary(o, ..) = inner_op.kind && o.node == BinOpKind::Lt {
|
||||
err.suggest_turbofish = Some(op.span.shrink_to_lo());
|
||||
} else {
|
||||
err.help_turbofish = Some(());
|
||||
}
|
||||
|
||||
let snapshot = self.create_snapshot_for_diagnostic();
|
||||
self.bump(); // `::`
|
||||
|
@ -1130,7 +1134,11 @@ impl<'a> Parser<'a> {
|
|||
} else if token::OpenDelim(Delimiter::Parenthesis) == self.token.kind {
|
||||
// We have high certainty that this was a bad turbofish at this point.
|
||||
// `foo< bar >(`
|
||||
err.suggest_turbofish = Some(op.span.shrink_to_lo());
|
||||
if let ExprKind::Binary(o, ..) = inner_op.kind && o.node == BinOpKind::Lt {
|
||||
err.suggest_turbofish = Some(op.span.shrink_to_lo());
|
||||
} else {
|
||||
err.help_turbofish = Some(());
|
||||
}
|
||||
// Consume the fn call arguments.
|
||||
match self.consume_fn_args() {
|
||||
Err(()) => Err(err.into_diagnostic(&self.sess.span_diagnostic)),
|
||||
|
|
|
@ -873,6 +873,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
if self.suggest_add_clone_to_arg(&obligation, &mut err, trait_predicate) {
|
||||
err.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
if self.suggest_impl_trait(&mut err, span, &obligation, trait_predicate) {
|
||||
err.emit();
|
||||
return;
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::infer::InferCtxt;
|
|||
use crate::traits::{NormalizeExt, ObligationCtxt};
|
||||
|
||||
use hir::def::CtorOf;
|
||||
use hir::HirId;
|
||||
use hir::{Expr, HirId};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_errors::{
|
||||
|
@ -206,6 +206,13 @@ pub trait TypeErrCtxtExt<'tcx> {
|
|||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
);
|
||||
|
||||
fn suggest_add_clone_to_arg(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn suggest_add_reference_to_arg(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
|
@ -1102,6 +1109,55 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn suggest_add_clone_to_arg(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> bool {
|
||||
let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty());
|
||||
let ty = self.tcx.erase_late_bound_regions(self_ty);
|
||||
let owner = self.tcx.hir().get_parent_item(obligation.cause.body_id);
|
||||
let Some(generics) = self.tcx.hir().get_generics(owner.def_id) else { return false };
|
||||
let ty::Ref(_, inner_ty, hir::Mutability::Not) = ty.kind() else { return false };
|
||||
let ty::Param(param) = inner_ty.kind() else { return false };
|
||||
let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() else { return false };
|
||||
let arg_node = self.tcx.hir().get(*arg_hir_id);
|
||||
let Node::Expr(Expr { kind: hir::ExprKind::Path(_), ..}) = arg_node else { return false };
|
||||
|
||||
let clone_trait = self.tcx.require_lang_item(LangItem::Clone, None);
|
||||
let has_clone = |ty| {
|
||||
self.type_implements_trait(clone_trait, [ty], obligation.param_env)
|
||||
.must_apply_modulo_regions()
|
||||
};
|
||||
|
||||
let new_obligation = self.mk_trait_obligation_with_new_self_ty(
|
||||
obligation.param_env,
|
||||
trait_pred.map_bound(|trait_pred| (trait_pred, *inner_ty)),
|
||||
);
|
||||
|
||||
if self.predicate_may_hold(&new_obligation) && has_clone(ty) {
|
||||
if !has_clone(param.to_ty(self.tcx)) {
|
||||
suggest_constraining_type_param(
|
||||
self.tcx,
|
||||
generics,
|
||||
err,
|
||||
param.name.as_str(),
|
||||
"Clone",
|
||||
Some(clone_trait),
|
||||
);
|
||||
}
|
||||
err.span_suggestion_verbose(
|
||||
obligation.cause.span.shrink_to_hi(),
|
||||
"consider using clone here",
|
||||
".clone()".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn suggest_add_reference_to_arg(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
|
|
|
@ -490,6 +490,8 @@ impl<T> Vec<T> {
|
|||
/// This is highly unsafe, due to the number of invariants that aren't
|
||||
/// checked:
|
||||
///
|
||||
/// * `ptr` must have been allocated using the global allocator, such as via
|
||||
/// the [`alloc::alloc`] function.
|
||||
/// * `T` needs to have the same alignment as what `ptr` was allocated with.
|
||||
/// (`T` having a less strict alignment is not sufficient, the alignment really
|
||||
/// needs to be equal to satisfy the [`dealloc`] requirement that memory must be
|
||||
|
@ -526,6 +528,7 @@ impl<T> Vec<T> {
|
|||
/// function.
|
||||
///
|
||||
/// [`String`]: crate::string::String
|
||||
/// [`alloc::alloc`]: crate::alloc::alloc
|
||||
/// [`dealloc`]: crate::alloc::GlobalAlloc::dealloc
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -681,6 +684,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||
/// This is highly unsafe, due to the number of invariants that aren't
|
||||
/// checked:
|
||||
///
|
||||
/// * `ptr` must be [*currently allocated*] via the given allocator `alloc`.
|
||||
/// * `T` needs to have the same alignment as what `ptr` was allocated with.
|
||||
/// (`T` having a less strict alignment is not sufficient, the alignment really
|
||||
/// needs to be equal to satisfy the [`dealloc`] requirement that memory must be
|
||||
|
@ -714,6 +718,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||
///
|
||||
/// [`String`]: crate::string::String
|
||||
/// [`dealloc`]: crate::alloc::GlobalAlloc::dealloc
|
||||
/// [*currently allocated*]: crate::alloc::Allocator#currently-allocated-memory
|
||||
/// [*fit*]: crate::alloc::Allocator#memory-fitting
|
||||
///
|
||||
/// # Examples
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::fmt;
|
||||
use crate::iter::{FusedIterator, TrustedLen};
|
||||
|
||||
/// Creates an iterator that lazily generates a value exactly once by invoking
|
||||
|
@ -66,12 +67,23 @@ pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
|
|||
///
|
||||
/// This `struct` is created by the [`once_with()`] function.
|
||||
/// See its documentation for more.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone)]
|
||||
#[stable(feature = "iter_once_with", since = "1.43.0")]
|
||||
pub struct OnceWith<F> {
|
||||
gen: Option<F>,
|
||||
}
|
||||
|
||||
#[stable(feature = "iter_once_with_debug", since = "CURRENT_RUSTC_VERSION")]
|
||||
impl<F> fmt::Debug for OnceWith<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
if self.gen.is_some() {
|
||||
f.write_str("OnceWith(Some(_))")
|
||||
} else {
|
||||
f.write_str("OnceWith(None)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "iter_once_with", since = "1.43.0")]
|
||||
impl<A, F: FnOnce() -> A> Iterator for OnceWith<F> {
|
||||
type Item = A;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::fmt;
|
||||
use crate::iter::{FusedIterator, TrustedLen};
|
||||
use crate::ops::Try;
|
||||
|
||||
|
@ -71,12 +72,19 @@ pub fn repeat_with<A, F: FnMut() -> A>(repeater: F) -> RepeatWith<F> {
|
|||
///
|
||||
/// This `struct` is created by the [`repeat_with()`] function.
|
||||
/// See its documentation for more.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[derive(Copy, Clone)]
|
||||
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
|
||||
pub struct RepeatWith<F> {
|
||||
repeater: F,
|
||||
}
|
||||
|
||||
#[stable(feature = "iterator_repeat_with_debug", since = "CURRENT_RUSTC_VERSION")]
|
||||
impl<F> fmt::Debug for RepeatWith<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("RepeatWith").finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
|
||||
impl<A, F: FnMut() -> A> Iterator for RepeatWith<F> {
|
||||
type Item = A;
|
||||
|
|
|
@ -5,7 +5,7 @@ goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
|||
write: (".search-input", "test")
|
||||
// To be SURE that the search will be run.
|
||||
press-key: 'Enter'
|
||||
wait-for: "#search h1" // The search element is empty before the first search
|
||||
wait-for: "#search h1" // The search element is empty before the first search
|
||||
// Check that the currently displayed element is search.
|
||||
wait-for: "#alternative-display #search"
|
||||
assert-attribute: ("#main-content", {"class": "content hidden"})
|
||||
|
|
|
@ -3,7 +3,7 @@ goto: "file://" + |DOC_PATH| + "/test_docs/struct.TypeWithImplDoc.html"
|
|||
|
||||
// The text is about 24px tall, so if there's a margin, then their position will be >24px apart
|
||||
compare-elements-position-near-false: (
|
||||
"#implementations-list > .implementors-toggle > .docblock > p",
|
||||
"#implementations-list > .implementors-toggle > .impl-items",
|
||||
{"y": 24}
|
||||
"#implementations-list > .implementors-toggle > .docblock > p",
|
||||
"#implementations-list > .implementors-toggle > .impl-items",
|
||||
{"y": 24}
|
||||
)
|
||||
|
|
|
@ -27,4 +27,8 @@ assert-css-false: (".content .out-of-band .since::before", { "content": "\"Since
|
|||
goto: "file://" + |DOC_PATH| + "/settings.html"
|
||||
size: (400, 600)
|
||||
// Ignored for now https://github.com/rust-lang/rust/issues/93784.
|
||||
// compare-elements-position-near-false: ("#preferred-light-theme .setting-name", "#preferred-light-theme .choice", {"y": 16})
|
||||
// compare-elements-position-near-false: (
|
||||
// "#preferred-light-theme .setting-name",
|
||||
// "#preferred-light-theme .choice",
|
||||
// {"y": 16},
|
||||
// )
|
||||
|
|
|
@ -31,13 +31,28 @@ define-function: (
|
|||
|
||||
call-function: (
|
||||
"check-logo",
|
||||
("ayu", "drop-shadow(rgb(255, 255, 255) 1px 0px 0px) drop-shadow(rgb(255, 255, 255) 0px 1px 0px) drop-shadow(rgb(255, 255, 255) -1px 0px 0px) drop-shadow(rgb(255, 255, 255) 0px -1px 0px)"),
|
||||
{
|
||||
"theme": "ayu",
|
||||
"filter": "drop-shadow(rgb(255, 255, 255) 1px 0px 0px) " +
|
||||
"drop-shadow(rgb(255, 255, 255) 0px 1px 0px) " +
|
||||
"drop-shadow(rgb(255, 255, 255) -1px 0px 0px) " +
|
||||
"drop-shadow(rgb(255, 255, 255) 0px -1px 0px)",
|
||||
},
|
||||
)
|
||||
call-function: (
|
||||
"check-logo",
|
||||
("dark", "drop-shadow(rgb(255, 255, 255) 1px 0px 0px) drop-shadow(rgb(255, 255, 255) 0px 1px 0px) drop-shadow(rgb(255, 255, 255) -1px 0px 0px) drop-shadow(rgb(255, 255, 255) 0px -1px 0px)"),
|
||||
{
|
||||
"theme": "dark",
|
||||
"filter": "drop-shadow(rgb(255, 255, 255) 1px 0px 0px) " +
|
||||
"drop-shadow(rgb(255, 255, 255) 0px 1px 0px) " +
|
||||
"drop-shadow(rgb(255, 255, 255) -1px 0px 0px) " +
|
||||
"drop-shadow(rgb(255, 255, 255) 0px -1px 0px)",
|
||||
},
|
||||
)
|
||||
call-function: (
|
||||
"check-logo",
|
||||
("light", "none"),
|
||||
{
|
||||
"theme": "light",
|
||||
"filter": "none",
|
||||
},
|
||||
)
|
||||
|
|
|
@ -5,25 +5,25 @@ store-property: (initialScrollTop, ".scraped-example-list > .scraped-example pre
|
|||
focus: ".scraped-example-list > .scraped-example .next"
|
||||
press-key: "Enter"
|
||||
assert-property-false: (".scraped-example-list > .scraped-example pre", {
|
||||
"scrollTop": |initialScrollTop|
|
||||
"scrollTop": |initialScrollTop|
|
||||
})
|
||||
focus: ".scraped-example-list > .scraped-example .prev"
|
||||
press-key: "Enter"
|
||||
assert-property: (".scraped-example-list > .scraped-example pre", {
|
||||
"scrollTop": |initialScrollTop|
|
||||
"scrollTop": |initialScrollTop|
|
||||
})
|
||||
|
||||
// The expand button increases the scrollHeight of the minimized code viewport
|
||||
store-property: (smallOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight")
|
||||
assert-property-false: (".scraped-example-list > .scraped-example pre", {
|
||||
"scrollHeight": |smallOffsetHeight|
|
||||
"scrollHeight": |smallOffsetHeight|
|
||||
})
|
||||
focus: ".scraped-example-list > .scraped-example .expand"
|
||||
press-key: "Enter"
|
||||
assert-property-false: (".scraped-example-list > .scraped-example pre", {
|
||||
"offsetHeight": |smallOffsetHeight|
|
||||
"offsetHeight": |smallOffsetHeight|
|
||||
})
|
||||
store-property: (fullOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight")
|
||||
assert-property: (".scraped-example-list > .scraped-example pre", {
|
||||
"scrollHeight": |fullOffsetHeight|
|
||||
"scrollHeight": |fullOffsetHeight|
|
||||
})
|
||||
|
|
|
@ -148,4 +148,4 @@ assert-text: ("#toggle-all-docs", "[+]")
|
|||
assert-property: (".sidebar", {"clientWidth": "200"})
|
||||
click: "#toggle-all-docs"
|
||||
assert-text: ("#toggle-all-docs", "[−]")
|
||||
assert-property: (".sidebar", {"clientWidth": "200"})
|
||||
assert-property: (".sidebar", {"clientWidth": "200"})
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// ignore-tidy-linelength
|
||||
// This test ensures that the items declaration content overflow is handled inside the <pre> directly.
|
||||
|
||||
// We need to disable this check because
|
||||
|
|
|
@ -22,8 +22,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn make() -> Self::Ty {
|
||||
| ^^^^^^^^
|
||||
= note: expected fn pointer `fn() -> <A<T> as Tr>::Ty`
|
||||
found fn pointer `fn() -> u8`
|
||||
= note: expected signature `fn() -> <A<T> as Tr>::Ty`
|
||||
found signature `fn() -> u8`
|
||||
|
||||
error[E0053]: method `make` has an incompatible type for trait
|
||||
--> $DIR/defaults-specialization.rs:35:18
|
||||
|
@ -42,8 +42,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn make() -> Self::Ty {
|
||||
| ^^^^^^^^
|
||||
= note: expected fn pointer `fn() -> <B<T> as Tr>::Ty`
|
||||
found fn pointer `fn() -> bool`
|
||||
= note: expected signature `fn() -> <B<T> as Tr>::Ty`
|
||||
found signature `fn() -> bool`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/defaults-specialization.rs:10:9
|
||||
|
|
|
@ -9,8 +9,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: expected fn pointer `fn(&i32) -> Pin<Box<dyn Future<Output = i32>>>`
|
||||
found fn pointer `fn(&i32) -> impl Future<Output = i32>`
|
||||
= note: expected signature `fn(&i32) -> Pin<Box<dyn Future<Output = i32>>>`
|
||||
found signature `fn(&i32) -> impl Future<Output = i32>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@ error[E0308]: method not compatible with trait
|
|||
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected fn pointer `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'_>)`
|
||||
found fn pointer `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'_>)`
|
||||
= note: expected signature `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'_>)`
|
||||
found signature `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'_>)`
|
||||
note: the lifetime `'c` as defined here...
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:27:24
|
||||
|
|
||||
|
@ -41,8 +41,8 @@ error[E0308]: method not compatible with trait
|
|||
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected fn pointer `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'_>)`
|
||||
found fn pointer `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'_>)`
|
||||
= note: expected signature `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'_>)`
|
||||
found signature `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'_>)`
|
||||
note: the lifetime `'c` as defined here...
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:27:24
|
||||
|
|
||||
|
|
|
@ -7,8 +7,8 @@ LL | fn poll(self, _: &mut Context<'_>) -> Poll<()> {
|
|||
| expected struct `Pin`, found struct `MyFuture`
|
||||
| help: change the self-receiver type to match the trait: `self: Pin<&mut MyFuture>`
|
||||
|
|
||||
= note: expected fn pointer `fn(Pin<&mut MyFuture>, &mut Context<'_>) -> Poll<_>`
|
||||
found fn pointer `fn(MyFuture, &mut Context<'_>) -> Poll<_>`
|
||||
= note: expected signature `fn(Pin<&mut MyFuture>, &mut Context<'_>) -> Poll<_>`
|
||||
found signature `fn(MyFuture, &mut Context<'_>) -> Poll<_>`
|
||||
|
||||
error[E0053]: method `foo` has an incompatible type for trait
|
||||
--> $DIR/bad-self-type.rs:22:18
|
||||
|
@ -24,8 +24,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn foo(self);
|
||||
| ^^^^
|
||||
= note: expected fn pointer `fn(MyFuture)`
|
||||
found fn pointer `fn(Box<MyFuture>)`
|
||||
= note: expected signature `fn(MyFuture)`
|
||||
found signature `fn(Box<MyFuture>)`
|
||||
|
||||
error[E0053]: method `bar` has an incompatible type for trait
|
||||
--> $DIR/bad-self-type.rs:24:18
|
||||
|
@ -38,8 +38,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn bar(self) -> Option<()>;
|
||||
| ^^^^^^^^^^
|
||||
= note: expected fn pointer `fn(MyFuture) -> Option<()>`
|
||||
found fn pointer `fn(MyFuture)`
|
||||
= note: expected signature `fn(MyFuture) -> Option<()>`
|
||||
found signature `fn(MyFuture)`
|
||||
help: change the output type to match the trait
|
||||
|
|
||||
LL | fn bar(self) -> Option<()> {}
|
||||
|
|
|
@ -7,8 +7,8 @@ LL | fn from(_: fn((), (), &mut ())) -> Self {
|
|||
| types differ in mutability
|
||||
| help: change the parameter type to match the trait: `for<'a> fn((), (), &'a ())`
|
||||
|
|
||||
= note: expected fn pointer `fn(for<'a> fn((), (), &'a ())) -> A`
|
||||
found fn pointer `fn(for<'a> fn((), (), &'a mut ())) -> A`
|
||||
= note: expected signature `fn(for<'a> fn((), (), &'a ())) -> A`
|
||||
found signature `fn(for<'a> fn((), (), &'a mut ())) -> A`
|
||||
|
||||
error[E0053]: method `from` has an incompatible type for trait
|
||||
--> $DIR/issue-90444.rs:11:16
|
||||
|
@ -19,8 +19,8 @@ LL | fn from(_: fn((), (), u64)) -> Self {
|
|||
| expected `u32`, found `u64`
|
||||
| help: change the parameter type to match the trait: `fn((), (), u32)`
|
||||
|
|
||||
= note: expected fn pointer `fn(fn((), (), u32)) -> B`
|
||||
found fn pointer `fn(fn((), (), u64)) -> B`
|
||||
= note: expected signature `fn(fn((), (), u32)) -> B`
|
||||
found signature `fn(fn((), (), u64)) -> B`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn b<C:Clone,D>(&self, x: C) -> C;
|
||||
| ^
|
||||
= note: expected fn pointer `fn(&E, F) -> F`
|
||||
found fn pointer `fn(&E, G) -> G`
|
||||
= note: expected signature `fn(&E, F) -> F`
|
||||
found signature `fn(&E, G) -> G`
|
||||
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
|
||||
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
// run-rustfix
|
||||
fn test(t: &mut dyn Iterator<Item=&u64>) -> u64 {
|
||||
*t.min().unwrap() //~ ERROR the `min` method cannot be invoked on
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let array = [0u64];
|
||||
test(&mut array.iter());
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// run-rustfix
|
||||
fn test(t: &dyn Iterator<Item=&u64>) -> u64 {
|
||||
*t.min().unwrap() //~ ERROR the `min` method cannot be invoked on
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let array = [0u64];
|
||||
test(&mut array.iter());
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
error: the `min` method cannot be invoked on `&dyn Iterator<Item = &u64>`
|
||||
--> $DIR/mutability-mismatch-arg.rs:3:9
|
||||
|
|
||||
LL | *t.min().unwrap()
|
||||
| ^^^
|
||||
|
|
||||
help: you need `&mut dyn Iterator<Item = &u64>` instead of `&dyn Iterator<Item = &u64>`
|
||||
|
|
||||
LL | fn test(t: &mut dyn Iterator<Item=&u64>) -> u64 {
|
||||
| +++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -4,7 +4,6 @@ pub trait MutTrait {
|
|||
fn function(&mut self)
|
||||
where
|
||||
Self: Sized;
|
||||
//~^ this has a `Sized` requirement
|
||||
}
|
||||
|
||||
impl MutTrait for MutType {
|
||||
|
@ -17,7 +16,6 @@ pub trait Trait {
|
|||
fn function(&self)
|
||||
where
|
||||
Self: Sized;
|
||||
//~^ this has a `Sized` requirement
|
||||
}
|
||||
|
||||
impl Trait for Type {
|
||||
|
@ -26,9 +24,9 @@ impl Trait for Type {
|
|||
|
||||
fn main() {
|
||||
(&MutType as &dyn MutTrait).function();
|
||||
//~^ ERROR the `function` method cannot be invoked on a trait object
|
||||
//~| NOTE you need `&mut dyn MutTrait` instead of `&dyn MutTrait`
|
||||
//~^ ERROR the `function` method cannot be invoked on `&dyn MutTrait`
|
||||
//~| HELP you need `&mut dyn MutTrait` instead of `&dyn MutTrait`
|
||||
(&mut Type as &mut dyn Trait).function();
|
||||
//~^ ERROR the `function` method cannot be invoked on a trait object
|
||||
//~| NOTE you need `&dyn Trait` instead of `&mut dyn Trait`
|
||||
//~^ ERROR the `function` method cannot be invoked on `&mut dyn Trait`
|
||||
//~| HELP you need `&dyn Trait` instead of `&mut dyn Trait`
|
||||
}
|
||||
|
|
|
@ -1,24 +1,18 @@
|
|||
error: the `function` method cannot be invoked on a trait object
|
||||
--> $DIR/mutability-mismatch.rs:28:33
|
||||
error: the `function` method cannot be invoked on `&dyn MutTrait`
|
||||
--> $DIR/mutability-mismatch.rs:26:33
|
||||
|
|
||||
LL | Self: Sized;
|
||||
| ----- this has a `Sized` requirement
|
||||
...
|
||||
LL | (&MutType as &dyn MutTrait).function();
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: you need `&mut dyn MutTrait` instead of `&dyn MutTrait`
|
||||
= help: you need `&mut dyn MutTrait` instead of `&dyn MutTrait`
|
||||
|
||||
error: the `function` method cannot be invoked on a trait object
|
||||
--> $DIR/mutability-mismatch.rs:31:35
|
||||
error: the `function` method cannot be invoked on `&mut dyn Trait`
|
||||
--> $DIR/mutability-mismatch.rs:29:35
|
||||
|
|
||||
LL | Self: Sized;
|
||||
| ----- this has a `Sized` requirement
|
||||
...
|
||||
LL | (&mut Type as &mut dyn Trait).function();
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: you need `&dyn Trait` instead of `&mut dyn Trait`
|
||||
= help: you need `&dyn Trait` instead of `&mut dyn Trait`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn foo<A: Debug>(&self, a: &A, b: &impl Debug);
|
||||
| ^^
|
||||
= note: expected fn pointer `fn(&(), &B, &impl Debug)`
|
||||
found fn pointer `fn(&(), &impl Debug, &B)`
|
||||
= note: expected signature `fn(&(), &B, &impl Debug)`
|
||||
found signature `fn(&(), &impl Debug, &B)`
|
||||
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
|
||||
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn owo(x: ()) -> impl Sized;
|
||||
| ^^
|
||||
= note: expected fn pointer `fn(())`
|
||||
found fn pointer `fn(u8)`
|
||||
= note: expected signature `fn(())`
|
||||
found signature `fn(u8)`
|
||||
|
||||
error[E0053]: method `owo` has an incompatible type for trait
|
||||
--> $DIR/method-signature-matches.rs:20:21
|
||||
|
@ -39,8 +39,8 @@ note: type in trait
|
|||
|
|
||||
LL | async fn owo(x: ()) {}
|
||||
| ^^
|
||||
= note: expected fn pointer `fn(()) -> _`
|
||||
found fn pointer `fn(u8) -> _`
|
||||
= note: expected signature `fn(()) -> _`
|
||||
found signature `fn(u8) -> _`
|
||||
|
||||
error[E0050]: method `calm_down_please` has 3 parameters but the declaration in trait `TooMuch::calm_down_please` has 0
|
||||
--> $DIR/method-signature-matches.rs:29:28
|
||||
|
@ -75,8 +75,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn early<'early, T>(x: &'early T) -> impl Sized;
|
||||
| ^^^^^^^^^
|
||||
= note: expected fn pointer `fn(&'early T)`
|
||||
found fn pointer `fn(&())`
|
||||
= note: expected signature `fn(&'early T)`
|
||||
found signature `fn(&())`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ LL | fn async_fn(&self, buff: &[u8]) -> impl Future<Output = Vec<u8>>;
|
|||
LL | fn async_fn<'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>> + 'a {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 Struct, &'2 [u8]) -> impl Future<Output = Vec<u8>> + '2`
|
||||
|
|
||||
= note: expected `fn(&'1 Struct, &'2 [u8]) -> impl Future<Output = Vec<u8>> + 'static`
|
||||
found `fn(&'1 Struct, &'2 [u8]) -> impl Future<Output = Vec<u8>> + '2`
|
||||
= note: expected signature `fn(&'1 Struct, &'2 [u8]) -> impl Future<Output = Vec<u8>> + 'static`
|
||||
found signature `fn(&'1 Struct, &'2 [u8]) -> impl Future<Output = Vec<u8>> + '2`
|
||||
= help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
|
||||
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn bar(&self) -> impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
= note: expected fn pointer `fn(&U) -> impl Sized`
|
||||
found fn pointer `fn(&U) -> U`
|
||||
= note: expected signature `fn(&U) -> impl Sized`
|
||||
found signature `fn(&U) -> U`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@ LL | fn eq(&self, _other: &(Foo, i32)) -> bool {
|
|||
| expected struct `Bar`, found opaque type
|
||||
| help: change the parameter type to match the trait: `&(a::Bar, i32)`
|
||||
|
|
||||
= note: expected fn pointer `fn(&a::Bar, &(a::Bar, i32)) -> _`
|
||||
found fn pointer `fn(&a::Bar, &(a::Foo, i32)) -> _`
|
||||
= note: expected signature `fn(&a::Bar, &(a::Bar, i32)) -> _`
|
||||
found signature `fn(&a::Bar, &(a::Foo, i32)) -> _`
|
||||
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:18:16
|
||||
|
@ -41,8 +41,8 @@ LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
|
|||
| expected opaque type, found struct `Bar`
|
||||
| help: change the parameter type to match the trait: `&(b::Foo, i32)`
|
||||
|
|
||||
= note: expected fn pointer `fn(&b::Bar, &(b::Foo, i32)) -> _`
|
||||
found fn pointer `fn(&b::Bar, &(b::Bar, i32)) -> _`
|
||||
= note: expected signature `fn(&b::Bar, &(b::Foo, i32)) -> _`
|
||||
found signature `fn(&b::Bar, &(b::Bar, i32)) -> _`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ LL | fn fmt(&self, x: &str) -> () { }
|
|||
| types differ in mutability
|
||||
| help: change the parameter type to match the trait: `&mut Formatter<'_>`
|
||||
|
|
||||
= note: expected fn pointer `fn(&MyType, &mut Formatter<'_>) -> Result<(), std::fmt::Error>`
|
||||
found fn pointer `fn(&MyType, &str)`
|
||||
= note: expected signature `fn(&MyType, &mut Formatter<'_>) -> Result<(), std::fmt::Error>`
|
||||
found signature `fn(&MyType, &str)`
|
||||
|
||||
error[E0050]: method `fmt` has 1 parameter but the declaration in trait `std::fmt::Display::fmt` has 2
|
||||
--> $DIR/trait_type.rs:12:11
|
||||
|
|
|
@ -7,8 +7,8 @@ struct Baz;
|
|||
impl Foo for Baz {
|
||||
fn bar(&mut self, other: &dyn Foo) {}
|
||||
//~^ ERROR method `bar` has an incompatible type for trait
|
||||
//~| expected fn pointer `fn(&mut Baz, &mut dyn Foo)`
|
||||
//~| found fn pointer `fn(&mut Baz, &dyn Foo)`
|
||||
//~| expected signature `fn(&mut Baz, &mut dyn Foo)`
|
||||
//~| found signature `fn(&mut Baz, &dyn Foo)`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -12,8 +12,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn bar(&mut self, other: &mut dyn Foo);
|
||||
| ^^^^^^^^^^^^
|
||||
= note: expected fn pointer `fn(&mut Baz, &mut dyn Foo)`
|
||||
found fn pointer `fn(&mut Baz, &dyn Foo)`
|
||||
= note: expected signature `fn(&mut Baz, &mut dyn Foo)`
|
||||
found signature `fn(&mut Baz, &dyn Foo)`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ impl<T: fmt::Debug> ops::FnOnce<(),> for Debuger<T> {
|
|||
type Output = ();
|
||||
fn call_once(self, _args: ()) {
|
||||
//~^ ERROR `call_once` has an incompatible type for trait
|
||||
//~| expected fn pointer `extern "rust-call" fn
|
||||
//~| found fn pointer `fn
|
||||
//~| expected signature `extern "rust-call" fn
|
||||
//~| found signature `fn
|
||||
println!("{:?}", self.x);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ error[E0053]: method `call_once` has an incompatible type for trait
|
|||
LL | fn call_once(self, _args: ()) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected "rust-call" fn, found "Rust" fn
|
||||
|
|
||||
= note: expected fn pointer `extern "rust-call" fn(Debuger<_>, ())`
|
||||
found fn pointer `fn(Debuger<_>, ())`
|
||||
= note: expected signature `extern "rust-call" fn(Debuger<_>, ())`
|
||||
found signature `fn(Debuger<_>, ())`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ LL | extern "rust-call" fn call(&self, (_,): (T,)) {}
|
|||
| expected `&T`, found type parameter `T`
|
||||
| help: change the parameter type to match the trait: `(&'a T,)`
|
||||
|
|
||||
= note: expected fn pointer `extern "rust-call" fn(&Foo, (&'a T,))`
|
||||
found fn pointer `extern "rust-call" fn(&Foo, (T,))`
|
||||
= note: expected signature `extern "rust-call" fn(&Foo, (&'a T,))`
|
||||
found signature `extern "rust-call" fn(&Foo, (T,))`
|
||||
|
||||
error[E0053]: method `call_mut` has an incompatible type for trait
|
||||
--> $DIR/issue-20225.rs:11:51
|
||||
|
@ -23,8 +23,8 @@ LL | extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
|
|||
| expected `&T`, found type parameter `T`
|
||||
| help: change the parameter type to match the trait: `(&'a T,)`
|
||||
|
|
||||
= note: expected fn pointer `extern "rust-call" fn(&mut Foo, (&'a T,))`
|
||||
found fn pointer `extern "rust-call" fn(&mut Foo, (T,))`
|
||||
= note: expected signature `extern "rust-call" fn(&mut Foo, (&'a T,))`
|
||||
found signature `extern "rust-call" fn(&mut Foo, (T,))`
|
||||
|
||||
error[E0053]: method `call_once` has an incompatible type for trait
|
||||
--> $DIR/issue-20225.rs:18:47
|
||||
|
@ -38,8 +38,8 @@ LL | extern "rust-call" fn call_once(self, (_,): (T,)) {}
|
|||
| expected `&T`, found type parameter `T`
|
||||
| help: change the parameter type to match the trait: `(&'a T,)`
|
||||
|
|
||||
= note: expected fn pointer `extern "rust-call" fn(Foo, (&'a T,))`
|
||||
found fn pointer `extern "rust-call" fn(Foo, (T,))`
|
||||
= note: expected signature `extern "rust-call" fn(Foo, (&'a T,))`
|
||||
found signature `extern "rust-call" fn(Foo, (T,))`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ LL | fn next(&mut self) -> Result<i32, i32> { Ok(7) }
|
|||
| expected enum `Option`, found enum `Result`
|
||||
| help: change the output type to match the trait: `Option<i32>`
|
||||
|
|
||||
= note: expected fn pointer `fn(&mut S) -> Option<i32>`
|
||||
found fn pointer `fn(&mut S) -> Result<i32, i32>`
|
||||
= note: expected signature `fn(&mut S) -> Option<i32>`
|
||||
found signature `fn(&mut S) -> Result<i32, i32>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -24,5 +24,4 @@ macro_rules! check_ptr_exist {
|
|||
fn main() {
|
||||
let item = stuff::Item::new();
|
||||
println!("{}", check_ptr_exist!(item, name));
|
||||
//~^ ERROR field `name` of struct `CObj` is private
|
||||
}
|
||||
|
|
|
@ -9,12 +9,6 @@ LL | println!("{}", check_ptr_exist!(item, name));
|
|||
|
|
||||
= note: this error originates in the macro `check_ptr_exist` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0616]: field `name` of struct `CObj` is private
|
||||
--> $DIR/issue-25386.rs:26:43
|
||||
|
|
||||
LL | println!("{}", check_ptr_exist!(item, name));
|
||||
| ^^^^ private field
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0616`.
|
||||
|
|
|
@ -4,8 +4,8 @@ error[E0308]: method not compatible with trait
|
|||
LL | fn next(&'a mut self) -> Option<Self::Item>
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected fn pointer `fn(&mut RepeatMut<'a, T>) -> Option<_>`
|
||||
found fn pointer `fn(&'a mut RepeatMut<'a, T>) -> Option<_>`
|
||||
= note: expected signature `fn(&mut RepeatMut<'a, T>) -> Option<_>`
|
||||
found signature `fn(&'a mut RepeatMut<'a, T>) -> Option<_>`
|
||||
note: the anonymous lifetime as defined here...
|
||||
--> $DIR/issue-37884.rs:6:5
|
||||
|
|
||||
|
|
|
@ -7,8 +7,8 @@ LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32;
|
|||
LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 i32, &'1 i32) -> &'1 i32`
|
||||
|
|
||||
= note: expected `fn(&'1 i32, &'a i32) -> &'a i32`
|
||||
found `fn(&'1 i32, &'1 i32) -> &'1 i32`
|
||||
= note: expected signature `fn(&'1 i32, &'a i32) -> &'a i32`
|
||||
found signature `fn(&'1 i32, &'1 i32) -> &'1 i32`
|
||||
= help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
|
||||
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn foo(x: u16);
|
||||
| ^^^
|
||||
= note: expected fn pointer `fn(u16)`
|
||||
found fn pointer `fn(i16)`
|
||||
= note: expected signature `fn(u16)`
|
||||
found signature `fn(i16)`
|
||||
|
||||
error[E0053]: method `bar` has an incompatible type for trait
|
||||
--> $DIR/E0053.rs:11:12
|
||||
|
@ -29,8 +29,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn bar(&self);
|
||||
| ^^^^^
|
||||
= note: expected fn pointer `fn(&Bar)`
|
||||
found fn pointer `fn(&mut Bar)`
|
||||
= note: expected signature `fn(&Bar)`
|
||||
found signature `fn(&mut Bar)`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@ LL | fn next(&mut self) -> Option<IteratorChunk<T, S>> {
|
|||
|
|
||||
= note: expected `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'static, T, S>>`
|
||||
|
|
||||
= note: expected `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'static, T, S>>`
|
||||
found `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'1, T, S>>`
|
||||
= note: expected signature `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'static, T, S>>`
|
||||
found signature `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'1, T, S>>`
|
||||
= help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
|
||||
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ LL | fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType>>;
|
|||
LL | fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType> + '_> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 T) -> Box<(dyn MyTrait<Item = &'1 T> + '1)>`
|
||||
|
|
||||
= note: expected `fn(&'1 T) -> Box<(dyn MyTrait<Item = &'1 T> + 'static)>`
|
||||
found `fn(&'1 T) -> Box<(dyn MyTrait<Item = &'1 T> + '1)>`
|
||||
= note: expected signature `fn(&'1 T) -> Box<(dyn MyTrait<Item = &'1 T> + 'static)>`
|
||||
found signature `fn(&'1 T) -> Box<(dyn MyTrait<Item = &'1 T> + '1)>`
|
||||
help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
|
||||
--> $DIR/issue-75361-mismatched-impl.rs:12:55
|
||||
|
|
||||
|
|
|
@ -12,8 +12,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn foo(x: u16);
|
||||
| ^^^
|
||||
= note: expected fn pointer `fn(u16)`
|
||||
found fn pointer `fn(i16)`
|
||||
= note: expected signature `fn(u16)`
|
||||
found signature `fn(i16)`
|
||||
|
||||
error[E0053]: method `bar` has an incompatible type for trait
|
||||
--> $DIR/trait-impl-fn-incompatibility.rs:10:28
|
||||
|
@ -29,8 +29,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn bar(&mut self, bar: &mut Bar);
|
||||
| ^^^^^^^^
|
||||
= note: expected fn pointer `fn(&mut Bar, &mut Bar)`
|
||||
found fn pointer `fn(&mut Bar, &Bar)`
|
||||
= note: expected signature `fn(&mut Bar, &mut Bar)`
|
||||
found signature `fn(&mut Bar, &Bar)`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
3
src/test/ui/parser/nested-bad-turbofish.rs
Normal file
3
src/test/ui/parser/nested-bad-turbofish.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
foo<<S as T>::V>(); //~ ERROR
|
||||
}
|
11
src/test/ui/parser/nested-bad-turbofish.stderr
Normal file
11
src/test/ui/parser/nested-bad-turbofish.stderr
Normal file
|
@ -0,0 +1,11 @@
|
|||
error: comparison operators cannot be chained
|
||||
--> $DIR/nested-bad-turbofish.rs:2:16
|
||||
|
|
||||
LL | foo<<S as T>::V>();
|
||||
| ^ ^
|
||||
|
|
||||
= help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
= help: or use `(...)` if you meant to specify fn arguments
|
||||
|
||||
error: aborting due to previous error
|
||||
|
20
src/test/ui/privacy/private-field-ty-err.rs
Normal file
20
src/test/ui/privacy/private-field-ty-err.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
fn main() {
|
||||
let x = foo::Foo::default();
|
||||
if x.len {
|
||||
//~^ ERROR field `len` of struct `Foo` is private
|
||||
println!("foo");
|
||||
}
|
||||
}
|
||||
|
||||
mod foo {
|
||||
#[derive(Default)]
|
||||
pub struct Foo {
|
||||
len: String,
|
||||
}
|
||||
|
||||
impl Foo {
|
||||
pub fn len(&self) -> usize {
|
||||
42
|
||||
}
|
||||
}
|
||||
}
|
14
src/test/ui/privacy/private-field-ty-err.stderr
Normal file
14
src/test/ui/privacy/private-field-ty-err.stderr
Normal file
|
@ -0,0 +1,14 @@
|
|||
error[E0616]: field `len` of struct `Foo` is private
|
||||
--> $DIR/private-field-ty-err.rs:3:10
|
||||
|
|
||||
LL | if x.len {
|
||||
| ^^^ private field
|
||||
|
|
||||
help: a method `len` also exists, call it with parentheses
|
||||
|
|
||||
LL | if x.len() {
|
||||
| ++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0616`.
|
|
@ -1,5 +1,5 @@
|
|||
fn test(t: &dyn Iterator<Item=&u64>) -> u64 {
|
||||
t.min().unwrap() //~ ERROR the `min` method cannot be invoked on a trait object
|
||||
t.min().unwrap() //~ ERROR the `min` method cannot be invoked on `&dyn Iterator<Item = &u64>`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
error: the `min` method cannot be invoked on a trait object
|
||||
error: the `min` method cannot be invoked on `&dyn Iterator<Item = &u64>`
|
||||
--> $DIR/imm-ref-trait-object.rs:2:8
|
||||
|
|
||||
LL | t.min().unwrap()
|
||||
| ^^^
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
|
|
||||
= note: this has a `Sized` requirement
|
||||
help: you need `&mut dyn Iterator<Item = &u64>` instead of `&dyn Iterator<Item = &u64>`
|
||||
|
|
||||
= note: you need `&mut dyn Iterator<Item = &u64>` instead of `&dyn Iterator<Item = &u64>`
|
||||
LL | fn test(t: &mut dyn Iterator<Item=&u64>) -> u64 {
|
||||
| +++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
23
src/test/ui/suggestions/issue-106443-sugg-clone-for-arg.rs
Normal file
23
src/test/ui/suggestions/issue-106443-sugg-clone-for-arg.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
#[derive(Clone)]
|
||||
struct S;
|
||||
|
||||
// without Clone
|
||||
struct T;
|
||||
|
||||
fn foo(_: S) {}
|
||||
|
||||
fn test1() {
|
||||
let s = &S;
|
||||
foo(s); //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn bar(_: T) {}
|
||||
fn test2() {
|
||||
let t = &T;
|
||||
bar(t); //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test1();
|
||||
test2();
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-106443-sugg-clone-for-arg.rs:11:9
|
||||
|
|
||||
LL | foo(s);
|
||||
| --- ^ expected struct `S`, found `&S`
|
||||
| |
|
||||
| arguments to this function are incorrect
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/issue-106443-sugg-clone-for-arg.rs:7:4
|
||||
|
|
||||
LL | fn foo(_: S) {}
|
||||
| ^^^ ----
|
||||
help: consider using clone here
|
||||
|
|
||||
LL | foo(s.clone());
|
||||
| ++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-106443-sugg-clone-for-arg.rs:17:9
|
||||
|
|
||||
LL | bar(t);
|
||||
| --- ^ expected struct `T`, found `&T`
|
||||
| |
|
||||
| arguments to this function are incorrect
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/issue-106443-sugg-clone-for-arg.rs:14:4
|
||||
|
|
||||
LL | fn bar(_: T) {}
|
||||
| ^^^ ----
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
20
src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.rs
Normal file
20
src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
#[derive(Clone)]
|
||||
struct S;
|
||||
|
||||
trait X {}
|
||||
|
||||
impl X for S {}
|
||||
|
||||
fn foo<T: X>(_: T) {}
|
||||
fn bar<T: X>(s: &T) {
|
||||
foo(s); //~ ERROR the trait bound `&T: X` is not satisfied
|
||||
}
|
||||
|
||||
fn bar_with_clone<T: X + Clone>(s: &T) {
|
||||
foo(s); //~ ERROR the trait bound `&T: X` is not satisfied
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = &S;
|
||||
bar(s);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
error[E0277]: the trait bound `&T: X` is not satisfied
|
||||
--> $DIR/issue-106443-sugg-clone-for-bound.rs:10:9
|
||||
|
|
||||
LL | foo(s);
|
||||
| ^ the trait `X` is not implemented for `&T`
|
||||
|
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | fn bar<T: X + Clone>(s: &T) {
|
||||
| +++++++
|
||||
help: consider using clone here
|
||||
|
|
||||
LL | foo(s.clone());
|
||||
| ++++++++
|
||||
|
||||
error[E0277]: the trait bound `&T: X` is not satisfied
|
||||
--> $DIR/issue-106443-sugg-clone-for-bound.rs:14:9
|
||||
|
|
||||
LL | foo(s);
|
||||
| ^ the trait `X` is not implemented for `&T`
|
||||
|
|
||||
help: consider using clone here
|
||||
|
|
||||
LL | foo(s.clone());
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
|
@ -6,8 +6,8 @@ impl Mumbo for usize {
|
|||
// Cannot have a larger effect than the trait:
|
||||
unsafe fn jumbo(&self, x: &usize) { *self + *x; }
|
||||
//~^ ERROR method `jumbo` has an incompatible type for trait
|
||||
//~| expected fn pointer `fn
|
||||
//~| found fn pointer `unsafe fn
|
||||
//~| expected signature `fn
|
||||
//~| found signature `unsafe fn
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -9,8 +9,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn jumbo(&self, x: &usize) -> usize;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: expected fn pointer `fn(&usize, &usize) -> usize`
|
||||
found fn pointer `unsafe fn(&usize, &usize)`
|
||||
= note: expected signature `fn(&usize, &usize) -> usize`
|
||||
found signature `unsafe fn(&usize, &usize)`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn foo(_: fn(u8) -> ());
|
||||
| ^^^^^^^^^^^^
|
||||
= note: expected fn pointer `fn(fn(u8))`
|
||||
found fn pointer `fn(fn(u16))`
|
||||
= note: expected signature `fn(fn(u8))`
|
||||
found signature `fn(fn(u16))`
|
||||
|
||||
error[E0053]: method `bar` has an incompatible type for trait
|
||||
--> $DIR/issue-35869.rs:13:15
|
||||
|
@ -29,8 +29,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn bar(_: Option<u8>);
|
||||
| ^^^^^^^^^^
|
||||
= note: expected fn pointer `fn(Option<u8>)`
|
||||
found fn pointer `fn(Option<u16>)`
|
||||
= note: expected signature `fn(Option<u8>)`
|
||||
found signature `fn(Option<u16>)`
|
||||
|
||||
error[E0053]: method `baz` has an incompatible type for trait
|
||||
--> $DIR/issue-35869.rs:15:15
|
||||
|
@ -46,8 +46,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn baz(_: (u8, u16));
|
||||
| ^^^^^^^^^
|
||||
= note: expected fn pointer `fn((u8, _))`
|
||||
found fn pointer `fn((u16, _))`
|
||||
= note: expected signature `fn((u8, _))`
|
||||
found signature `fn((u16, _))`
|
||||
|
||||
error[E0053]: method `qux` has an incompatible type for trait
|
||||
--> $DIR/issue-35869.rs:17:17
|
||||
|
@ -63,8 +63,8 @@ note: type in trait
|
|||
|
|
||||
LL | fn qux() -> u8;
|
||||
| ^^
|
||||
= note: expected fn pointer `fn() -> u8`
|
||||
found fn pointer `fn() -> u16`
|
||||
= note: expected signature `fn() -> u8`
|
||||
found signature `fn() -> u16`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@ error[E0308]: method not compatible with trait
|
|||
LL | fn foo(x: Foo<'b,'a>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected fn pointer `fn(Foo<'a, 'b>)`
|
||||
found fn pointer `fn(Foo<'b, 'a>)`
|
||||
= note: expected signature `fn(Foo<'a, 'b>)`
|
||||
found signature `fn(Foo<'b, 'a>)`
|
||||
note: the lifetime `'b` as defined here...
|
||||
--> $DIR/matching-lifetimes.rs:13:9
|
||||
|
|
||||
|
@ -23,8 +23,8 @@ error[E0308]: method not compatible with trait
|
|||
LL | fn foo(x: Foo<'b,'a>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected fn pointer `fn(Foo<'a, 'b>)`
|
||||
found fn pointer `fn(Foo<'b, 'a>)`
|
||||
= note: expected signature `fn(Foo<'a, 'b>)`
|
||||
found signature `fn(Foo<'b, 'a>)`
|
||||
note: the lifetime `'a` as defined here...
|
||||
--> $DIR/matching-lifetimes.rs:13:6
|
||||
|
|
||||
|
|
|
@ -7,8 +7,8 @@ LL | fn get_relation(&self) -> To;
|
|||
LL | fn get_relation(&self) -> &ProofReader {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 Article) -> &'1 ProofReader`
|
||||
|
|
||||
= note: expected `fn(&'1 Article) -> &'2 ProofReader`
|
||||
found `fn(&'1 Article) -> &'1 ProofReader`
|
||||
= note: expected signature `fn(&'1 Article) -> &'2 ProofReader`
|
||||
found signature `fn(&'1 Article) -> &'1 ProofReader`
|
||||
help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
|
||||
--> $DIR/param-without-lifetime-constraint.rs:10:31
|
||||
|
|
||||
|
|
|
@ -7,8 +7,8 @@ LL | fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self, &Self>;
|
|||
LL | fn column_result(value: ValueRef<'_>) -> FromSqlResult<&str, &&str> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(ValueRef<'1>) -> Result<(&'1 str, &'1 &'1 str), FromSqlError>`
|
||||
|
|
||||
= note: expected `fn(ValueRef<'1>) -> Result<(&'2 str, &'1 &'2 str), FromSqlError>`
|
||||
found `fn(ValueRef<'1>) -> Result<(&'1 str, &'1 &'1 str), FromSqlError>`
|
||||
= note: expected signature `fn(ValueRef<'1>) -> Result<(&'2 str, &'1 &'2 str), FromSqlError>`
|
||||
found signature `fn(ValueRef<'1>) -> Result<(&'1 str, &'1 &'1 str), FromSqlError>`
|
||||
help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
|
||||
--> $DIR/self-without-lifetime-constraint.rs:41:60
|
||||
|
|
||||
|
|
|
@ -7,8 +7,8 @@ trait Foo {
|
|||
impl Foo for u32 {
|
||||
fn len(&self) -> u32 { *self }
|
||||
//~^ ERROR method `len` has an incompatible type for trait
|
||||
//~| expected fn pointer `unsafe fn(&u32) -> _`
|
||||
//~| found fn pointer `fn(&u32) -> _`
|
||||
//~| expected signature `unsafe fn(&u32) -> _`
|
||||
//~| found signature `fn(&u32) -> _`
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
|
|
@ -9,8 +9,8 @@ note: type in trait
|
|||
|
|
||||
LL | unsafe fn len(&self) -> u32;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: expected fn pointer `unsafe fn(&u32) -> _`
|
||||
found fn pointer `fn(&u32) -> _`
|
||||
= note: expected signature `unsafe fn(&u32) -> _`
|
||||
found signature `fn(&u32) -> _`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ LL | fn mul(self, s: &f64) -> Vec1 {
|
|||
| expected `f64`, found `&f64`
|
||||
| help: change the parameter type to match the trait: `f64`
|
||||
|
|
||||
= note: expected fn pointer `fn(Vec1, f64) -> Vec1`
|
||||
found fn pointer `fn(Vec1, &f64) -> Vec1`
|
||||
= note: expected signature `fn(Vec1, f64) -> Vec1`
|
||||
found signature `fn(Vec1, &f64) -> Vec1`
|
||||
|
||||
error[E0053]: method `mul` has an incompatible type for trait
|
||||
--> $DIR/wrong-mul-method-signature.rs:33:21
|
||||
|
@ -19,8 +19,8 @@ LL | fn mul(self, s: f64) -> Vec2 {
|
|||
| expected struct `Vec2`, found `f64`
|
||||
| help: change the parameter type to match the trait: `Vec2`
|
||||
|
|
||||
= note: expected fn pointer `fn(Vec2, Vec2) -> f64`
|
||||
found fn pointer `fn(Vec2, f64) -> Vec2`
|
||||
= note: expected signature `fn(Vec2, Vec2) -> f64`
|
||||
found signature `fn(Vec2, f64) -> Vec2`
|
||||
|
||||
error[E0053]: method `mul` has an incompatible type for trait
|
||||
--> $DIR/wrong-mul-method-signature.rs:52:29
|
||||
|
@ -31,8 +31,8 @@ LL | fn mul(self, s: f64) -> f64 {
|
|||
| expected `i32`, found `f64`
|
||||
| help: change the output type to match the trait: `i32`
|
||||
|
|
||||
= note: expected fn pointer `fn(Vec3, _) -> i32`
|
||||
found fn pointer `fn(Vec3, _) -> f64`
|
||||
= note: expected signature `fn(Vec3, _) -> i32`
|
||||
found signature `fn(Vec3, _) -> f64`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/wrong-mul-method-signature.rs:63:45
|
||||
|
|
|
@ -25,6 +25,7 @@ use std::path::Path;
|
|||
/// displayed on the console with --example.
|
||||
const ERROR_CODE_COLS: usize = 80;
|
||||
const COLS: usize = 100;
|
||||
const GOML_COLS: usize = 120;
|
||||
|
||||
const LINES: usize = 3000;
|
||||
|
||||
|
@ -230,7 +231,8 @@ pub fn check(path: &Path, bad: &mut bool) {
|
|||
walk(path, &mut skip, &mut |entry, contents| {
|
||||
let file = entry.path();
|
||||
let filename = file.file_name().unwrap().to_string_lossy();
|
||||
let extensions = [".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h", ".md", ".css", ".ftl"];
|
||||
let extensions =
|
||||
[".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h", ".md", ".css", ".ftl", ".goml"];
|
||||
if extensions.iter().all(|e| !filename.ends_with(e)) || filename.starts_with(".#") {
|
||||
return;
|
||||
}
|
||||
|
@ -255,8 +257,15 @@ pub fn check(path: &Path, bad: &mut bool) {
|
|||
|
||||
let extension = file.extension().unwrap().to_string_lossy();
|
||||
let is_error_code = extension == "md" && is_in(file, "src", "error_codes");
|
||||
let is_goml_code = extension == "goml";
|
||||
|
||||
let max_columns = if is_error_code { ERROR_CODE_COLS } else { COLS };
|
||||
let max_columns = if is_error_code {
|
||||
ERROR_CODE_COLS
|
||||
} else if is_goml_code {
|
||||
GOML_COLS
|
||||
} else {
|
||||
COLS
|
||||
};
|
||||
|
||||
let can_contain = contents.contains("// ignore-tidy-")
|
||||
|| contents.contains("# ignore-tidy-")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue