Skip to content

Commit 081e5d3

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 fe348cd + c0d717f commit 081e5d3

File tree

94 files changed

+1124
-118
lines changed

Some content is hidden

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

94 files changed

+1124
-118
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);

compiler/rustc_next_trait_solver/src/solve/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,9 @@ where
339339
fn opaque_type_is_rigid(&self, def_id: I::DefId) -> bool {
340340
match self.typing_mode() {
341341
// Opaques are never rigid outside of analysis mode.
342-
TypingMode::Coherence | TypingMode::PostAnalysis => false,
342+
TypingMode::Coherence | TypingMode::CheckObjectOverlap | TypingMode::PostAnalysis => {
343+
false
344+
}
343345
// During analysis, opaques are rigid unless they may be defined by
344346
// the current body.
345347
TypingMode::Analysis { defining_opaque_types_and_generators: non_rigid_opaques }

compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ where
240240
// would be relevant if any of the nested goals refer to the `term`.
241241
// This is not the case here and we only prefer adding an ambiguous
242242
// nested goal for consistency.
243-
ty::TypingMode::Coherence => {
243+
ty::TypingMode::Coherence | ty::TypingMode::CheckObjectOverlap => {
244244
ecx.add_goal(GoalSource::Misc, goal.with(cx, PredicateKind::Ambiguous));
245245
return ecx
246246
.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
@@ -280,7 +280,7 @@ where
280280
// would be relevant if any of the nested goals refer to the `term`.
281281
// This is not the case here and we only prefer adding an ambiguous
282282
// nested goal for consistency.
283-
ty::TypingMode::Coherence => {
283+
ty::TypingMode::Coherence | ty::TypingMode::CheckObjectOverlap => {
284284
ecx.add_goal(GoalSource::Misc, goal.with(cx, PredicateKind::Ambiguous));
285285
return ecx
286286
.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);

compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ where
2323
let expected = goal.predicate.term.as_type().expect("no such thing as an opaque const");
2424

2525
match self.typing_mode() {
26-
TypingMode::Coherence => {
26+
TypingMode::Coherence | TypingMode::CheckObjectOverlap => {
2727
// An impossible opaque type bound is the only way this goal will fail
2828
// e.g. assigning `impl Copy := NotCopy`
2929
self.add_item_bounds_for_hidden_type(

compiler/rustc_next_trait_solver/src/solve/search_graph.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ where
5858
// example where this would matter. We likely should change these cycles to `NoSolution`
5959
// even in coherence once this is a bit more settled.
6060
PathKind::Inductive => match input.typing_mode {
61-
TypingMode::Coherence => {
61+
TypingMode::Coherence | TypingMode::CheckObjectOverlap => {
6262
response_no_constraints(cx, input, Certainty::overflow(false))
6363
}
6464
TypingMode::Analysis { .. }

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ where
7070
// In intercrate mode, this is ambiguous. But outside of intercrate,
7171
// it's not a real impl.
7272
(ty::ImplPolarity::Reservation, _) => match ecx.typing_mode() {
73-
TypingMode::Coherence => Certainty::AMBIGUOUS,
73+
TypingMode::Coherence | TypingMode::CheckObjectOverlap => Certainty::AMBIGUOUS,
7474
TypingMode::Analysis { .. }
7575
| TypingMode::Borrowck { .. }
7676
| TypingMode::PostBorrowckAnalysis { .. }
@@ -1257,7 +1257,7 @@ where
12571257
&mut self,
12581258
mut candidates: Vec<Candidate<I>>,
12591259
) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolution> {
1260-
if let TypingMode::Coherence = self.typing_mode() {
1260+
if let TypingMode::Coherence | TypingMode::CheckObjectOverlap = self.typing_mode() {
12611261
let all_candidates: Vec<_> = candidates.into_iter().map(|c| c.result).collect();
12621262
return if let Some(response) = self.try_merge_responses(&all_candidates) {
12631263
Ok((response, Some(TraitGoalProvenVia::Misc)))
@@ -1360,6 +1360,7 @@ where
13601360
}
13611361
}
13621362
TypingMode::Coherence
1363+
| TypingMode::CheckObjectOverlap
13631364
| TypingMode::PostAnalysis
13641365
| TypingMode::Borrowck { defining_opaque_types: _ }
13651366
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => {}

compiler/rustc_trait_selection/src/solve/delegate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
178178
// get a result which isn't correct for all monomorphizations.
179179
match self.typing_mode() {
180180
TypingMode::Coherence
181+
| TypingMode::CheckObjectOverlap
181182
| TypingMode::Analysis { .. }
182183
| TypingMode::Borrowck { .. }
183184
| TypingMode::PostBorrowckAnalysis { .. } => false,

0 commit comments

Comments
 (0)