Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Rollup of 8 pull requests #106616

Merged
merged 24 commits into from
Jan 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e7a7778
Suggest possible clone when we have &T
chenyukang Jan 3, 2023
1a0a613
Apply suggestions from code review
chenyukang Jan 6, 2023
ce4afed
comments feedback
chenyukang Jan 5, 2023
1eb828e
Structured suggestion for `&mut dyn Iterator` when possible
estebank Jan 2, 2023
670a6f1
Change wording to avoid being misleading
estebank Jan 2, 2023
2631a5d
Turn `IllegalSizedBound` into struct variant
estebank Jan 5, 2023
b693365
fix rebase
estebank Jan 6, 2023
6082729
use type_implements_trait to check Param clone
chenyukang Jan 6, 2023
eddb479
Don't derive Debug for `OnceWith` & `RepeatWith`
Jan 7, 2023
288e89b
Document that `Vec::from_raw_parts[_in]` must be given a pointer from…
kpreid Jan 7, 2023
49f849a
Mention signature rather than fn pointers when comparing impl/trait m…
compiler-errors Dec 24, 2022
0e570e5
Remove extra space
chenyukang Jan 8, 2023
59aa421
Suppress type errors that come from private fields
compiler-errors Jan 8, 2023
65fae26
Add goml scripts to tidy checks
GuillaumeGomez Jan 8, 2023
31b39be
Fix tidy issues in goml scripts
GuillaumeGomez Jan 8, 2023
6fdb54d
Do not emit structured suggestion for turbofish with wrong span
estebank Jan 8, 2023
db87e27
Rollup merge of #104163 - H4x5:once-repeat-with-debug, r=dtolnay
compiler-errors Jan 9, 2023
6afd161
Rollup merge of #106131 - compiler-errors:not-ptrs, r=davidtwco
compiler-errors Jan 9, 2023
334426b
Rollup merge of #106363 - estebank:mutability-mismatch-arg, r=Nilstrieb
compiler-errors Jan 9, 2023
eefc44b
Rollup merge of #106497 - chenyukang:yukang/fix-106443-sugg-clone, r=…
compiler-errors Jan 9, 2023
70f1566
Rollup merge of #106584 - kpreid:vec-allocator, r=JohnTitor
compiler-errors Jan 9, 2023
29420a8
Rollup merge of #106600 - compiler-errors:no-private-field-ty-err, r=…
compiler-errors Jan 9, 2023
bb6a88a
Rollup merge of #106602 - GuillaumeGomez:tidy-goml-scripts, r=Mark-Si…
compiler-errors Jan 9, 2023
5e8e97f
Rollup merge of #106606 - estebank:bad-nested-turbofish, r=compiler-e…
compiler-errors Jan 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_error_messages/locales/en-US/infer.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
36 changes: 14 additions & 22 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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)?;
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand All @@ -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 {
Expand Down
30 changes: 30 additions & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
11 changes: 8 additions & 3 deletions compiler/rustc_hir_typeck/src/method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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"),
}
}
Expand Down Expand Up @@ -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)
Expand Down
41 changes: 37 additions & 4 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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();
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)) }
}
}
20 changes: 18 additions & 2 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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"))
}
Expand Down Expand Up @@ -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))
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
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;
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;
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down
Loading