Skip to content

Commit 7bb9888

Browse files
committed
Auto merge of #135402 - matthiaskrgr:rollup-cz7hs13, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #129259 (Add inherent versions of MaybeUninit methods for slices) - #135374 (Suggest typo fix when trait path expression is typo'ed) - #135377 (Make MIR cleanup for functions with impossible predicates into a real MIR pass) - #135378 (Remove a bunch of diagnostic stashing that doesn't do anything) - #135397 (compiletest: add erroneous variant to `string_enum`s conversions error) - #135398 (add more crash tests) r? `@ghost` `@rustbot` modify labels: rollup
2 parents c0f6a1c + 2fd11d0 commit 7bb9888

File tree

53 files changed

+853
-542
lines changed

Some content is hidden

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

53 files changed

+853
-542
lines changed

compiler/rustc_arena/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ impl<T> ArenaChunk<T> {
7878
// been initialized.
7979
unsafe {
8080
let slice = self.storage.as_mut();
81-
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len]));
81+
slice[..len].assume_init_drop();
8282
}
8383
}
8484
}

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
152152
let (Ok(e) | Err(e)) = prev
153153
.build_mismatch_error(
154154
&OpaqueHiddenType { ty, span: concrete_type.span },
155-
opaque_type_key.def_id,
156155
infcx.tcx,
157156
)
158157
.map(|d| d.emit());

compiler/rustc_errors/src/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -566,9 +566,7 @@ pub enum StashKey {
566566
/// FRU syntax
567567
MaybeFruTypo,
568568
CallAssocMethod,
569-
TraitMissingMethod,
570569
AssociatedTypeSuggestion,
571-
OpaqueHiddenTypeMismatch,
572570
MaybeForgetReturn,
573571
/// Query cycle detected, stashing in favor of a better error.
574572
Cycle,

compiler/rustc_hir_analysis/src/check/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ fn sanity_check_found_hidden_type<'tcx>(
575575
} else {
576576
let span = tcx.def_span(key.def_id);
577577
let other = ty::OpaqueHiddenType { ty: hidden_ty, span };
578-
Err(ty.build_mismatch_error(&other, key.def_id, tcx)?.emit())
578+
Err(ty.build_mismatch_error(&other, tcx)?.emit())
579579
}
580580
}
581581

compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs

+7-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use rustc_errors::StashKey;
21
use rustc_hir::def::DefKind;
32
use rustc_hir::def_id::LocalDefId;
43
use rustc_hir::intravisit::{self, Visitor};
@@ -45,7 +44,7 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
4544
if !hidden.ty.references_error() {
4645
for concrete_type in locator.typeck_types {
4746
if concrete_type.ty != tcx.erase_regions(hidden.ty) {
48-
if let Ok(d) = hidden.build_mismatch_error(&concrete_type, def_id, tcx) {
47+
if let Ok(d) = hidden.build_mismatch_error(&concrete_type, tcx) {
4948
d.emit();
5049
}
5150
}
@@ -121,7 +120,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
121120
if !hidden.ty.references_error() {
122121
for concrete_type in locator.typeck_types {
123122
if concrete_type.ty != tcx.erase_regions(hidden.ty) {
124-
if let Ok(d) = hidden.build_mismatch_error(&concrete_type, def_id, tcx) {
123+
if let Ok(d) = hidden.build_mismatch_error(&concrete_type, tcx) {
125124
d.emit();
126125
}
127126
}
@@ -285,9 +284,8 @@ impl TaitConstraintLocator<'_> {
285284
debug!(?concrete_type, "found constraint");
286285
if let Some(prev) = &mut self.found {
287286
if concrete_type.ty != prev.ty {
288-
let (Ok(guar) | Err(guar)) = prev
289-
.build_mismatch_error(&concrete_type, self.def_id, self.tcx)
290-
.map(|d| d.emit());
287+
let (Ok(guar) | Err(guar)) =
288+
prev.build_mismatch_error(&concrete_type, self.tcx).map(|d| d.emit());
291289
prev.ty = Ty::new_error(self.tcx, guar);
292290
}
293291
} else {
@@ -361,11 +359,8 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
361359
);
362360
if let Some(prev) = &mut hir_opaque_ty {
363361
if concrete_type.ty != prev.ty {
364-
if let Ok(d) = prev.build_mismatch_error(&concrete_type, def_id, tcx) {
365-
d.stash(
366-
tcx.def_span(opaque_type_key.def_id),
367-
StashKey::OpaqueHiddenTypeMismatch,
368-
);
362+
if let Ok(d) = prev.build_mismatch_error(&concrete_type, tcx) {
363+
d.emit();
369364
}
370365
}
371366
} else {
@@ -435,9 +430,7 @@ impl RpitConstraintChecker<'_> {
435430
debug!(?concrete_type, "found constraint");
436431

437432
if concrete_type.ty != self.found.ty {
438-
if let Ok(d) =
439-
self.found.build_mismatch_error(&concrete_type, self.def_id, self.tcx)
440-
{
433+
if let Ok(d) = self.found.build_mismatch_error(&concrete_type, self.tcx) {
441434
d.emit();
442435
}
443436
}

compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs

+50-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ use rustc_ast::TraitObjectSyntax;
22
use rustc_errors::codes::*;
33
use rustc_errors::{Diag, EmissionGuarantee, ErrorGuaranteed, StashKey, Suggestions};
44
use rustc_hir as hir;
5-
use rustc_hir::def::{DefKind, Res};
5+
use rustc_hir::def::{DefKind, Namespace, Res};
6+
use rustc_hir::def_id::DefId;
67
use rustc_lint_defs::Applicability;
78
use rustc_lint_defs::builtin::BARE_TRAIT_OBJECTS;
89
use rustc_span::Span;
10+
use rustc_span::edit_distance::find_best_match_for_name;
911
use rustc_trait_selection::error_reporting::traits::suggestions::NextTypeParamName;
1012

1113
use super::HirTyLowerer;
@@ -86,7 +88,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
8688
// Check if the impl trait that we are considering is an impl of a local trait.
8789
self.maybe_suggest_blanket_trait_impl(self_ty, &mut diag);
8890
self.maybe_suggest_assoc_ty_bound(self_ty, &mut diag);
89-
// In case there is an associate type with the same name
91+
self.maybe_suggest_typoed_method(
92+
self_ty,
93+
poly_trait_ref.trait_ref.trait_def_id(),
94+
&mut diag,
95+
);
96+
// In case there is an associated type with the same name
9097
// Add the suggestion to this error
9198
if let Some(mut sugg) =
9299
tcx.dcx().steal_non_err(self_ty.span, StashKey::AssociatedTypeSuggestion)
@@ -96,7 +103,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
96103
s1.append(s2);
97104
sugg.cancel();
98105
}
99-
diag.stash(self_ty.span, StashKey::TraitMissingMethod)
106+
Some(diag.emit())
100107
} else {
101108
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, |lint| {
102109
lint.primary_message("trait objects without an explicit `dyn` are deprecated");
@@ -343,4 +350,44 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
343350
);
344351
}
345352
}
353+
354+
fn maybe_suggest_typoed_method(
355+
&self,
356+
self_ty: &hir::Ty<'_>,
357+
trait_def_id: Option<DefId>,
358+
diag: &mut Diag<'_>,
359+
) {
360+
let tcx = self.tcx();
361+
let Some(trait_def_id) = trait_def_id else {
362+
return;
363+
};
364+
let hir::Node::Expr(hir::Expr {
365+
kind: hir::ExprKind::Path(hir::QPath::TypeRelative(path_ty, segment)),
366+
..
367+
}) = tcx.parent_hir_node(self_ty.hir_id)
368+
else {
369+
return;
370+
};
371+
if path_ty.hir_id != self_ty.hir_id {
372+
return;
373+
}
374+
let names: Vec<_> = tcx
375+
.associated_items(trait_def_id)
376+
.in_definition_order()
377+
.filter(|assoc| assoc.kind.namespace() == Namespace::ValueNS)
378+
.map(|cand| cand.name)
379+
.collect();
380+
if let Some(typo) = find_best_match_for_name(&names, segment.ident.name, None) {
381+
diag.span_suggestion_verbose(
382+
segment.ident.span,
383+
format!(
384+
"you may have misspelled this associated item, causing `{}` \
385+
to be interpreted as a type rather than a trait",
386+
tcx.item_name(trait_def_id),
387+
),
388+
typo,
389+
Applicability::MaybeIncorrect,
390+
);
391+
}
392+
}
346393
}

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+1-23
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::slice;
33

44
use rustc_abi::FieldIdx;
55
use rustc_data_structures::fx::FxHashSet;
6-
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey};
6+
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan};
77
use rustc_hir::def::{CtorOf, DefKind, Res};
88
use rustc_hir::def_id::DefId;
99
use rustc_hir::intravisit::Visitor;
@@ -806,17 +806,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
806806
let item_name = item_segment.ident;
807807
let result = self
808808
.resolve_fully_qualified_call(span, item_name, ty.normalized, qself.span, hir_id)
809-
.map(|r| {
810-
// lint bare trait if the method is found in the trait
811-
if span.edition().at_least_rust_2021() {
812-
self.dcx().try_steal_modify_and_emit_err(
813-
qself.span,
814-
StashKey::TraitMissingMethod,
815-
|_err| {},
816-
);
817-
}
818-
r
819-
})
820809
.or_else(|error| {
821810
let guar = self
822811
.dcx()
@@ -840,17 +829,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
840829
);
841830
}
842831

843-
// Emit the diagnostic for bare traits. (We used to cancel for slightly better
844-
// error messages, but cancelling stashed diagnostics is no longer allowed because
845-
// it causes problems when tracking whether errors have actually occurred.)
846-
if span.edition().at_least_rust_2021() {
847-
self.dcx().try_steal_modify_and_emit_err(
848-
qself.span,
849-
StashKey::TraitMissingMethod,
850-
|_err| {},
851-
);
852-
}
853-
854832
if item_name.name != kw::Empty {
855833
self.report_method_error(
856834
hir_id,

compiler/rustc_hir_typeck/src/writeback.rs

+3-10
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use std::mem;
66

77
use rustc_data_structures::unord::ExtendUnord;
8-
use rustc_errors::{ErrorGuaranteed, StashKey};
8+
use rustc_errors::ErrorGuaranteed;
99
use rustc_hir as hir;
1010
use rustc_hir::HirId;
1111
use rustc_hir::intravisit::{self, Visitor};
@@ -582,15 +582,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
582582
&& last_opaque_ty.ty != hidden_type.ty
583583
{
584584
assert!(!self.fcx.next_trait_solver());
585-
if let Ok(d) = hidden_type.build_mismatch_error(
586-
&last_opaque_ty,
587-
opaque_type_key.def_id,
588-
self.tcx(),
589-
) {
590-
d.stash(
591-
self.tcx().def_span(opaque_type_key.def_id),
592-
StashKey::OpaqueHiddenTypeMismatch,
593-
);
585+
if let Ok(d) = hidden_type.build_mismatch_error(&last_opaque_ty, self.tcx()) {
586+
d.emit();
594587
}
595588
}
596589
}

compiler/rustc_middle/src/ty/mod.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
3232
use rustc_data_structures::intern::Interned;
3333
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
3434
use rustc_data_structures::steal::Steal;
35-
use rustc_errors::{Diag, ErrorGuaranteed, StashKey};
35+
use rustc_errors::{Diag, ErrorGuaranteed};
3636
use rustc_hir::LangItem;
3737
use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
3838
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
@@ -782,18 +782,8 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
782782
pub fn build_mismatch_error(
783783
&self,
784784
other: &Self,
785-
opaque_def_id: LocalDefId,
786785
tcx: TyCtxt<'tcx>,
787786
) -> Result<Diag<'tcx>, ErrorGuaranteed> {
788-
// We used to cancel here for slightly better error messages, but
789-
// cancelling stashed diagnostics is no longer allowed because it
790-
// causes problems when tracking whether errors have actually
791-
// occurred.
792-
tcx.sess.dcx().try_steal_modify_and_emit_err(
793-
tcx.def_span(opaque_def_id),
794-
StashKey::OpaqueHiddenTypeMismatch,
795-
|_err| {},
796-
);
797787
(self.ty, other.ty).error_reported()?;
798788
// Found different concrete types for the opaque type.
799789
let sub_diag = if self.span == other.span {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//! Check if it's even possible to satisfy the 'where' clauses
2+
//! for this item.
3+
//!
4+
//! It's possible to `#!feature(trivial_bounds)]` to write
5+
//! a function with impossible to satisfy clauses, e.g.:
6+
//! `fn foo() where String: Copy {}`.
7+
//!
8+
//! We don't usually need to worry about this kind of case,
9+
//! since we would get a compilation error if the user tried
10+
//! to call it. However, since we optimize even without any
11+
//! calls to the function, we need to make sure that it even
12+
//! makes sense to try to evaluate the body.
13+
//!
14+
//! If there are unsatisfiable where clauses, then all bets are
15+
//! off, and we just give up.
16+
//!
17+
//! We manually filter the predicates, skipping anything that's not
18+
//! "global". We are in a potentially generic context
19+
//! (e.g. we are evaluating a function without instantiating generic
20+
//! parameters, so this filtering serves two purposes:
21+
//!
22+
//! 1. We skip evaluating any predicates that we would
23+
//! never be able prove are unsatisfiable (e.g. `<T as Foo>`
24+
//! 2. We avoid trying to normalize predicates involving generic
25+
//! parameters (e.g. `<T as Foo>::MyItem`). This can confuse
26+
//! the normalization code (leading to cycle errors), since
27+
//! it's usually never invoked in this way.
28+
29+
use rustc_middle::mir::{Body, START_BLOCK, TerminatorKind};
30+
use rustc_middle::ty::{TyCtxt, TypeVisitableExt};
31+
use rustc_trait_selection::traits;
32+
use tracing::trace;
33+
34+
use crate::pass_manager::MirPass;
35+
36+
pub(crate) struct ImpossiblePredicates;
37+
38+
impl<'tcx> MirPass<'tcx> for ImpossiblePredicates {
39+
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
40+
let predicates = tcx
41+
.predicates_of(body.source.def_id())
42+
.predicates
43+
.iter()
44+
.filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None });
45+
if traits::impossible_predicates(tcx, traits::elaborate(tcx, predicates).collect()) {
46+
trace!("found unsatisfiable predicates for {:?}", body.source);
47+
// Clear the body to only contain a single `unreachable` statement.
48+
let bbs = body.basic_blocks.as_mut();
49+
bbs.raw.truncate(1);
50+
bbs[START_BLOCK].statements.clear();
51+
bbs[START_BLOCK].terminator_mut().kind = TerminatorKind::Unreachable;
52+
body.var_debug_info.clear();
53+
body.local_decls.raw.truncate(body.arg_count + 1);
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)