Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 7d2afcd

Browse files
committed
Auto merge of rust-lang#140824 - compiler-errors:typing-mode, r=<try>
[CRATER] probe fallout of `dyn` overlap r? lcnr for vibes, not to merge obviously
2 parents 667247d + d3c50fc commit 7d2afcd

File tree

95 files changed

+1125
-119
lines changed

Some content is hidden

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

95 files changed

+1125
-119
lines changed

‎compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,12 @@ fn check_trait_item<'tcx>(
391391
// Check that an item definition in a subtrait is shadowing a supertrait item.
392392
lint_item_shadowing_supertrait_item(tcx, def_id);
393393

394+
for blanket_impl_def_id in tcx.all_impls(def_id.to_def_id()) {
395+
if !blanket_impl_def_id.is_local() {
396+
tcx.ensure_ok().lint_object_blanket_impl((blanket_impl_def_id, def_id.to_def_id()));
397+
}
398+
}
399+
394400
let mut res = check_associated_item(tcx, def_id, span, method_sig);
395401

396402
if matches!(trait_item.kind, hir::TraitItemKind::Fn(..)) {

‎compiler/rustc_hir_analysis/src/impl_wf_check.rs

Lines changed: 144 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,23 @@
1010
1111
use std::assert_matches::debug_assert_matches;
1212

13-
use min_specialization::check_min_specialization;
13+
use itertools::Itertools;
1414
use rustc_data_structures::fx::FxHashSet;
1515
use rustc_errors::codes::*;
1616
use rustc_hir::def::DefKind;
17-
use rustc_hir::def_id::LocalDefId;
18-
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
19-
use rustc_span::ErrorGuaranteed;
17+
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
18+
use rustc_infer::infer::TyCtxtInferExt;
19+
use rustc_lint_defs::builtin::DYN_OVERLAP;
20+
use rustc_middle::ty::{
21+
self, ExistentialPredicateStableCmpExt, Ty, TyCtxt, TypeVisitableExt, TypingMode, Upcast,
22+
elaborate,
23+
};
24+
use rustc_span::{DUMMY_SP, ErrorGuaranteed, sym};
25+
use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt};
2026

2127
use crate::constrained_generic_params as cgp;
2228
use crate::errors::UnconstrainedGenericParameter;
29+
use crate::impl_wf_check::min_specialization::check_min_specialization;
2330

2431
mod min_specialization;
2532

@@ -68,6 +75,22 @@ pub(crate) fn check_impl_wf(
6875
if tcx.features().min_specialization() {
6976
res = res.and(check_min_specialization(tcx, impl_def_id));
7077
}
78+
79+
if let Some(trait_def_id) = tcx.trait_id_of_impl(impl_def_id.to_def_id()) {
80+
for &subtrait_def_id in tcx
81+
.crates(())
82+
.into_iter()
83+
.copied()
84+
.chain([LOCAL_CRATE])
85+
.flat_map(|cnum| tcx.traits(cnum))
86+
{
87+
if ty::elaborate::supertrait_def_ids(tcx, subtrait_def_id).contains(&trait_def_id) {
88+
tcx.ensure_ok()
89+
.lint_object_blanket_impl((impl_def_id.to_def_id(), subtrait_def_id));
90+
}
91+
}
92+
}
93+
7194
res
7295
}
7396

@@ -234,3 +257,120 @@ pub(crate) fn enforce_impl_non_lifetime_params_are_constrained(
234257
}
235258
res
236259
}
260+
261+
pub(crate) fn lint_object_blanket_impl<'tcx>(
262+
tcx: TyCtxt<'tcx>,
263+
(impl_def_id, trait_def_id): (DefId, DefId),
264+
) {
265+
if tcx.is_diagnostic_item(sym::Any, trait_def_id) {
266+
return;
267+
}
268+
269+
if !tcx.is_dyn_compatible(trait_def_id) {
270+
return;
271+
}
272+
273+
let infcx = tcx.infer_ctxt().with_next_trait_solver(true).build(TypingMode::CheckObjectOverlap);
274+
275+
let principal_trait_args = infcx.fresh_args_for_item(DUMMY_SP, trait_def_id);
276+
let principal_trait = ty::TraitRef::new_from_args(tcx, trait_def_id, principal_trait_args);
277+
278+
let mut needed_associated_types = vec![];
279+
let clause: ty::Clause<'tcx> = ty::TraitRef::identity(tcx, trait_def_id).upcast(tcx);
280+
for clause in elaborate::elaborate(tcx, [clause]).filter_only_self() {
281+
let clause = clause.instantiate_supertrait(tcx, ty::Binder::dummy(principal_trait));
282+
283+
let bound_predicate = clause.kind();
284+
match bound_predicate.skip_binder() {
285+
ty::ClauseKind::Trait(pred) => {
286+
// FIXME(negative_bounds): Handle this correctly...
287+
let trait_ref = tcx.anonymize_bound_vars(bound_predicate.rebind(pred.trait_ref));
288+
needed_associated_types.extend(
289+
tcx.associated_items(pred.trait_ref.def_id)
290+
.in_definition_order()
291+
// We only care about associated types.
292+
.filter(|item| item.is_type())
293+
// No RPITITs -- they're not dyn-compatible for now.
294+
.filter(|item| !item.is_impl_trait_in_trait())
295+
// If the associated type has a `where Self: Sized` bound,
296+
// we do not need to constrain the associated type.
297+
.filter(|item| !tcx.generics_require_sized_self(item.def_id))
298+
.map(|item| (item.def_id, trait_ref)),
299+
);
300+
}
301+
_ => (),
302+
}
303+
}
304+
305+
let mut data: Vec<_> = [ty::Binder::dummy(ty::ExistentialPredicate::Trait(
306+
ty::ExistentialTraitRef::erase_self_ty(tcx, principal_trait),
307+
))]
308+
.into_iter()
309+
.chain(needed_associated_types.into_iter().map(|(def_id, trait_ref)| {
310+
trait_ref.map_bound(|trait_ref| {
311+
ty::ExistentialPredicate::Projection(ty::ExistentialProjection::erase_self_ty(
312+
tcx,
313+
ty::ProjectionPredicate {
314+
projection_term: ty::AliasTerm::new_from_args(tcx, def_id, trait_ref.args),
315+
term: infcx.next_ty_var(DUMMY_SP).into(),
316+
},
317+
))
318+
})
319+
}))
320+
.collect();
321+
data.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
322+
323+
let self_ty = Ty::new_dynamic(
324+
tcx,
325+
tcx.mk_poly_existential_predicates(&data),
326+
tcx.lifetimes.re_erased,
327+
ty::Dyn,
328+
);
329+
330+
let impl_args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
331+
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(tcx, impl_args);
332+
333+
let ocx = ObligationCtxt::new(&infcx);
334+
let Ok(()) =
335+
ocx.eq(&ObligationCause::dummy(), ty::ParamEnv::empty(), principal_trait, impl_trait_ref)
336+
else {
337+
return;
338+
};
339+
let Ok(()) =
340+
ocx.eq(&ObligationCause::dummy(), ty::ParamEnv::empty(), self_ty, impl_trait_ref.self_ty())
341+
else {
342+
return;
343+
};
344+
345+
ocx.register_obligations(
346+
tcx.predicates_of(impl_def_id).instantiate(tcx, impl_args).into_iter().map(
347+
|(clause, _)| {
348+
Obligation::new(tcx, ObligationCause::dummy(), ty::ParamEnv::empty(), clause)
349+
},
350+
),
351+
);
352+
353+
if !ocx.select_where_possible().is_empty() {
354+
return;
355+
}
356+
357+
let local_def_id = if let Some(impl_def_id) = impl_def_id.as_local() {
358+
impl_def_id
359+
} else if let Some(trait_def_id) = trait_def_id.as_local() {
360+
trait_def_id
361+
} else {
362+
panic!()
363+
};
364+
let hir_id = tcx.local_def_id_to_hir_id(local_def_id);
365+
366+
let self_ty = infcx.resolve_vars_if_possible(self_ty);
367+
368+
tcx.node_span_lint(DYN_OVERLAP, hir_id, tcx.def_span(local_def_id), |diag| {
369+
diag.primary_message("hi");
370+
diag.span_label(
371+
tcx.def_span(trait_def_id),
372+
format!("built-in `{self_ty}` implementation for this trait"),
373+
);
374+
diag.span_label(tcx.def_span(impl_def_id), "overlaps with this blanket impl");
375+
});
376+
}

‎compiler/rustc_hir_analysis/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ pub fn provide(providers: &mut Providers) {
171171
inherit_sig_for_delegation_item: delegation::inherit_sig_for_delegation_item,
172172
enforce_impl_non_lifetime_params_are_constrained:
173173
impl_wf_check::enforce_impl_non_lifetime_params_are_constrained,
174+
lint_object_blanket_impl: impl_wf_check::lint_object_blanket_impl,
174175
..*providers
175176
};
176177
}

‎compiler/rustc_infer/src/infer/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,7 @@ impl<'tcx> InferCtxt<'tcx> {
968968
// and post-borrowck analysis mode. We may need to modify its uses
969969
// to support PostBorrowckAnalysis in the old solver as well.
970970
TypingMode::Coherence
971+
| TypingMode::CheckObjectOverlap
971972
| TypingMode::PostBorrowckAnalysis { .. }
972973
| TypingMode::PostAnalysis => false,
973974
}
@@ -1260,6 +1261,7 @@ impl<'tcx> InferCtxt<'tcx> {
12601261
TypingMode::non_body_analysis()
12611262
}
12621263
mode @ (ty::TypingMode::Coherence
1264+
| TypingMode::CheckObjectOverlap
12631265
| ty::TypingMode::PostBorrowckAnalysis { .. }
12641266
| ty::TypingMode::PostAnalysis) => mode,
12651267
};

‎compiler/rustc_infer/src/infer/opaque_types/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ impl<'tcx> InferCtxt<'tcx> {
8787
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
8888
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => {
8989
let def_id = def_id.expect_local();
90-
if let ty::TypingMode::Coherence = self.typing_mode() {
90+
if let ty::TypingMode::Coherence | ty::TypingMode::CheckObjectOverlap =
91+
self.typing_mode()
92+
{
9193
// See comment on `insert_hidden_type` for why this is sufficient in coherence
9294
return Some(self.register_hidden_type(
9395
OpaqueTypeKey { def_id, args },
@@ -226,7 +228,7 @@ impl<'tcx> InferCtxt<'tcx> {
226228
// these are the same span, but not in cases like `-> (impl
227229
// Foo, impl Bar)`.
228230
match self.typing_mode() {
229-
ty::TypingMode::Coherence => {
231+
ty::TypingMode::Coherence | ty::TypingMode::CheckObjectOverlap=> {
230232
// During intercrate we do not define opaque types but instead always
231233
// force ambiguity unless the hidden type is known to not implement
232234
// our trait.

‎compiler/rustc_infer/src/infer/relate/generalize.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,10 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
519519
//
520520
// cc trait-system-refactor-initiative#108
521521
if self.infcx.next_trait_solver()
522-
&& !matches!(self.infcx.typing_mode(), TypingMode::Coherence)
522+
&& !matches!(
523+
self.infcx.typing_mode(),
524+
TypingMode::Coherence | TypingMode::CheckObjectOverlap
525+
)
523526
&& self.in_alias
524527
{
525528
inner.type_variables().equate(vid, new_var_id);
@@ -650,7 +653,10 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
650653
// See the comment for type inference variables
651654
// for more details.
652655
if self.infcx.next_trait_solver()
653-
&& !matches!(self.infcx.typing_mode(), TypingMode::Coherence)
656+
&& !matches!(
657+
self.infcx.typing_mode(),
658+
TypingMode::Coherence | TypingMode::CheckObjectOverlap
659+
)
654660
&& self.in_alias
655661
{
656662
variable_table.union(vid, new_var_id);

‎compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ declare_lint_pass! {
3737
DEPRECATED_SAFE_2024,
3838
DEPRECATED_WHERE_CLAUSE_LOCATION,
3939
DUPLICATE_MACRO_ATTRIBUTES,
40+
DYN_OVERLAP,
4041
ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
4142
ELIDED_LIFETIMES_IN_PATHS,
4243
ELIDED_NAMED_LIFETIMES,
@@ -5067,3 +5068,14 @@ declare_lint! {
50675068
reference: "issue #138762 <https://github.com/rust-lang/rust/issues/138762>",
50685069
};
50695070
}
5071+
5072+
declare_lint! {
5073+
/// The `dyn_overlap` lint is one of the lints of all time.
5074+
///
5075+
/// ### Uwu
5076+
///
5077+
/// Owo
5078+
pub DYN_OVERLAP,
5079+
Forbid,
5080+
"owo",
5081+
}

‎compiler/rustc_middle/src/query/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,10 @@ rustc_queries! {
527527
anon
528528
}
529529

530+
query lint_object_blanket_impl(_: (DefId, DefId)) {
531+
desc { "u if wu" }
532+
}
533+
530534
/// Set of param indexes for type params that are in the type's representation
531535
query params_in_repr(key: DefId) -> &'tcx rustc_index::bit_set::DenseBitSet<u32> {
532536
desc { "finding type parameters in the representation" }

‎compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ where
380380

381381
let mut candidates = vec![];
382382

383-
if let TypingMode::Coherence = self.typing_mode() {
383+
if let TypingMode::Coherence | TypingMode::CheckObjectOverlap= self.typing_mode() {
384384
if let Ok(candidate) = self.consider_coherence_unknowable_candidate(goal) {
385385
return vec![candidate];
386386
}
@@ -831,7 +831,7 @@ where
831831
candidates: &mut Vec<Candidate<I>>,
832832
) {
833833
match self.typing_mode() {
834-
TypingMode::Coherence => return,
834+
TypingMode::Coherence | TypingMode::CheckObjectOverlap=> return,
835835
TypingMode::Analysis { .. }
836836
| TypingMode::Borrowck { .. }
837837
| TypingMode::PostBorrowckAnalysis { .. }

‎compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -948,7 +948,8 @@ where
948948
GoalSource::TypeRelating
949949
}
950950
// FIXME(-Znext-solver=coinductive): should these WF goals also be unproductive?
951-
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => GoalSource::Misc,
951+
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_))
952+
| ty::PredicateKind::Ambiguous => GoalSource::Misc,
952953
p => unreachable!("unexpected nested goal in `relate`: {p:?}"),
953954
};
954955
self.add_goal(source, goal);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /