Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d2e8ecd

Browse files
committedFeb 16, 2024
Auto merge of rust-lang#121188 - GuillaumeGomez:rollup-bejz7fq, r=GuillaumeGomez
Rollup of 6 pull requests Successful merges: - rust-lang#119928 (suggest `into_iter()` when `Iterator` method called on `impl IntoIterator`) - rust-lang#121020 (Avoid an ICE in diagnostics) - rust-lang#121111 (For E0038, suggest associated type if available) - rust-lang#121137 (Add clippy into the known `cfg` list) - rust-lang#121179 (allow mutable references in const values when they point to no memory) - rust-lang#121181 (Fix an ICE in the recursion lint) r? `@ghost` `@rustbot` modify labels: rollup
2 parents ae9d7b0 + f82875e commit d2e8ecd

File tree

55 files changed

+592
-440
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+592
-440
lines changed
 

‎compiler/rustc_errors/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@ pub enum StashKey {
526526
MaybeFruTypo,
527527
CallAssocMethod,
528528
TraitMissingMethod,
529+
AssociatedTypeSuggestion,
529530
OpaqueHiddenTypeMismatch,
530531
MaybeForgetReturn,
531532
/// Query cycle detected, stashing in favor of a better error.

‎compiler/rustc_hir_typeck/src/method/suggest.rs

+96
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,93 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
109109
self.autoderef(span, ty).any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
110110
}
111111

112+
fn impl_into_iterator_should_be_iterator(
113+
&self,
114+
ty: Ty<'tcx>,
115+
span: Span,
116+
unsatisfied_predicates: &Vec<(
117+
ty::Predicate<'_>,
118+
Option<ty::Predicate<'_>>,
119+
Option<ObligationCause<'_>>,
120+
)>,
121+
) -> bool {
122+
fn predicate_bounds_generic_param<'tcx>(
123+
predicate: ty::Predicate<'_>,
124+
generics: &'tcx ty::Generics,
125+
generic_param: &ty::GenericParamDef,
126+
tcx: TyCtxt<'tcx>,
127+
) -> bool {
128+
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) =
129+
predicate.kind().as_ref().skip_binder()
130+
{
131+
let ty::TraitPredicate { trait_ref: ty::TraitRef { args, .. }, .. } = trait_pred;
132+
if args.is_empty() {
133+
return false;
134+
}
135+
let Some(arg_ty) = args[0].as_type() else {
136+
return false;
137+
};
138+
let ty::Param(param) = arg_ty.kind() else {
139+
return false;
140+
};
141+
// Is `generic_param` the same as the arg for this trait predicate?
142+
generic_param.index == generics.type_param(&param, tcx).index
143+
} else {
144+
false
145+
}
146+
}
147+
148+
fn is_iterator_predicate(predicate: ty::Predicate<'_>, tcx: TyCtxt<'_>) -> bool {
149+
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) =
150+
predicate.kind().as_ref().skip_binder()
151+
{
152+
tcx.is_diagnostic_item(sym::Iterator, trait_pred.trait_ref.def_id)
153+
} else {
154+
false
155+
}
156+
}
157+
158+
// Does the `ty` implement `IntoIterator`?
159+
let Some(into_iterator_trait) = self.tcx.get_diagnostic_item(sym::IntoIterator) else {
160+
return false;
161+
};
162+
let trait_ref = ty::TraitRef::new(self.tcx, into_iterator_trait, [ty]);
163+
let cause = ObligationCause::new(span, self.body_id, ObligationCauseCode::MiscObligation);
164+
let obligation = Obligation::new(self.tcx, cause, self.param_env, trait_ref);
165+
if !self.predicate_must_hold_modulo_regions(&obligation) {
166+
return false;
167+
}
168+
169+
match ty.kind() {
170+
ty::Param(param) => {
171+
let generics = self.tcx.generics_of(self.body_id);
172+
let generic_param = generics.type_param(&param, self.tcx);
173+
for unsatisfied in unsatisfied_predicates.iter() {
174+
// The parameter implements `IntoIterator`
175+
// but it has called a method that requires it to implement `Iterator`
176+
if predicate_bounds_generic_param(
177+
unsatisfied.0,
178+
generics,
179+
generic_param,
180+
self.tcx,
181+
) && is_iterator_predicate(unsatisfied.0, self.tcx)
182+
{
183+
return true;
184+
}
185+
}
186+
}
187+
ty::Alias(ty::AliasKind::Opaque, _) => {
188+
for unsatisfied in unsatisfied_predicates.iter() {
189+
if is_iterator_predicate(unsatisfied.0, self.tcx) {
190+
return true;
191+
}
192+
}
193+
}
194+
_ => return false,
195+
}
196+
false
197+
}
198+
112199
#[instrument(level = "debug", skip(self))]
113200
pub fn report_method_error(
114201
&self,
@@ -555,6 +642,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
555642
"`count` is defined on `{iterator_trait}`, which `{rcvr_ty}` does not implement"
556643
));
557644
}
645+
} else if self.impl_into_iterator_should_be_iterator(rcvr_ty, span, unsatisfied_predicates)
646+
{
647+
err.span_label(span, format!("`{rcvr_ty}` is not an iterator"));
648+
err.multipart_suggestion_verbose(
649+
"call `.into_iter()` first",
650+
vec![(span.shrink_to_lo(), format!("into_iter()."))],
651+
Applicability::MaybeIncorrect,
652+
);
653+
return Some(err);
558654
} else if !unsatisfied_predicates.is_empty() && matches!(rcvr_ty.kind(), ty::Param(_)) {
559655
// We special case the situation where we are looking for `_` in
560656
// `<TypeParam as _>::method` because otherwise the machinery will look for blanket

‎compiler/rustc_middle/src/mir/interpret/error.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_macros::HashStable;
1212
use rustc_session::CtfeBacktrace;
1313
use rustc_span::{def_id::DefId, Span, DUMMY_SP};
1414
use rustc_target::abi::{call, Align, Size, VariantIdx, WrappingRange};
15+
use rustc_type_ir::Mutability;
1516

1617
use std::borrow::Cow;
1718
use std::{any::Any, backtrace::Backtrace, fmt};
@@ -367,15 +368,15 @@ pub enum UndefinedBehaviorInfo<'tcx> {
367368

368369
#[derive(Debug, Clone, Copy)]
369370
pub enum PointerKind {
370-
Ref,
371+
Ref(Mutability),
371372
Box,
372373
}
373374

374375
impl IntoDiagnosticArg for PointerKind {
375376
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
376377
DiagnosticArgValue::Str(
377378
match self {
378-
Self::Ref => "ref",
379+
Self::Ref(_) => "ref",
379380
Self::Box => "box",
380381
}
381382
.into(),
@@ -408,7 +409,7 @@ impl From<PointerKind> for ExpectedKind {
408409
fn from(x: PointerKind) -> ExpectedKind {
409410
match x {
410411
PointerKind::Box => ExpectedKind::Box,
411-
PointerKind::Ref => ExpectedKind::Reference,
412+
PointerKind::Ref(_) => ExpectedKind::Reference,
412413
}
413414
}
414415
}
@@ -419,7 +420,7 @@ pub enum ValidationErrorKind<'tcx> {
419420
PartialPointer,
420421
PtrToUninhabited { ptr_kind: PointerKind, ty: Ty<'tcx> },
421422
PtrToStatic { ptr_kind: PointerKind },
422-
MutableRefInConst,
423+
MutableRefInConstOrStatic,
423424
ConstRefToMutable,
424425
ConstRefToExtern,
425426
MutableRefToImmutable,
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.