Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit bf5ff66

Browse files
committed
Auto merge of rust-lang#140558 - lcnr:wf-emit-projection, r=<try>
wf: emit projection goal for aliases To check that their normalization succeeds in the current environment. This eagerly detects ambiguous and diverging aliases. r? `@compiler-errors`
2 parents 0e517d3 + 283c81f commit bf5ff66

File tree

33 files changed

+340
-100
lines changed

33 files changed

+340
-100
lines changed

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ fn compare_method_predicate_entailment<'tcx>(
393393
for obligation in obligations {
394394
debug!(?obligation);
395395
match obligation.predicate.kind().skip_binder() {
396-
// We need to register Projection oblgiations too, because we may end up with
396+
// We need to register Projection obligations too, because we may end up with
397397
// an implied `X::Item: 'a`, which gets desugared into `X::Item = ?0`, `?0: 'a`.
398398
// If we only register the region outlives obligation, this leads to an unconstrained var.
399399
// See `implied_bounds_entailment_alias_var.rs` test.

compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,6 @@ fn check_predicates<'tcx>(
381381
let obligations =
382382
wf::obligations(infcx, tcx.param_env(impl1_def_id), impl1_def_id, 0, term, span)
383383
.unwrap();
384-
385-
assert!(!obligations.has_infer());
386384
impl2_predicates
387385
.extend(traits::elaborate(tcx, obligations).map(|obligation| obligation.predicate))
388386
}

compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3939
self.type_matches_expected_vid(expected_vid, data.self_ty())
4040
}
4141
ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
42-
self.type_matches_expected_vid(expected_vid, data.projection_term.self_ty())
42+
match data.projection_term.kind(self.tcx) {
43+
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
44+
self.type_matches_expected_vid(expected_vid, data.projection_term.self_ty())
45+
}
46+
ty::AliasTermKind::InherentTy
47+
| ty::AliasTermKind::OpaqueTy
48+
| ty::AliasTermKind::FreeTy
49+
| ty::AliasTermKind::UnevaluatedConst => false,
50+
}
4351
}
4452
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
4553
| ty::PredicateKind::Subtype(..)

compiler/rustc_trait_selection/src/traits/wf.rs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -509,8 +509,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
509509
let obligations = self.nominal_obligations(data.def_id, args);
510510
self.out.extend(obligations);
511511
}
512-
513-
data.args.visit_with(self);
514512
}
515513

516514
fn add_wf_preds_for_projection_args(&mut self, args: GenericArgsRef<'tcx>) {
@@ -771,13 +769,34 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
771769
// Simple cases that are WF if their type args are WF.
772770
}
773771

774-
ty::Alias(ty::Projection | ty::Opaque | ty::Free, data) => {
775-
let obligations = self.nominal_obligations(data.def_id, data.args);
776-
self.out.extend(obligations);
777-
}
778-
ty::Alias(ty::Inherent, data) => {
779-
self.add_wf_preds_for_inherent_projection(data);
780-
return; // Subtree handled by compute_inherent_projection.
772+
ty::Alias(kind, data) => {
773+
let code = ObligationCauseCode::Misc;
774+
let cause = self.cause(code);
775+
let inf = self.infcx.next_ty_var(rustc_span::DUMMY_SP);
776+
let projection_goal_supported =
777+
matches!(kind, ty::Projection) || self.infcx.next_trait_solver();
778+
if projection_goal_supported && !data.has_escaping_bound_vars() {
779+
let obligation: traits::PredicateObligation<'tcx> =
780+
traits::Obligation::with_depth(
781+
self.tcx(),
782+
cause,
783+
self.recursion_depth,
784+
self.param_env,
785+
ty::ProjectionPredicate {
786+
projection_term: data.into(),
787+
term: inf.into(),
788+
},
789+
);
790+
self.out.push(obligation);
791+
}
792+
793+
match kind {
794+
ty::Projection | ty::Opaque | ty::Free => {
795+
let obligations = self.nominal_obligations(data.def_id, data.args);
796+
self.out.extend(obligations);
797+
}
798+
ty::Inherent => self.add_wf_preds_for_inherent_projection(data),
799+
}
781800
}
782801

783802
ty::Adt(def, args) => {

tests/ui/associated-inherent-types/normalization-overflow.stderr renamed to tests/ui/associated-inherent-types/normalization-overflow.current.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: overflow evaluating associated type `T::This`
2-
--> $DIR/normalization-overflow.rs:9:17
2+
--> $DIR/normalization-overflow.rs:12:17
33
|
44
LL | type This = Self::This;
55
| ^^^^^^^^^^
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0271]: type mismatch resolving `T::This normalizes-to _`
2+
--> $DIR/normalization-overflow.rs:12:17
3+
|
4+
LL | type This = Self::This;
5+
| ^^^^^^^^^^ types differ
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0271`.
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
//@ revisions: current next
2+
//@[next] compile-flags: -Znext-solver
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
14
#![feature(inherent_associated_types)]
25
#![allow(incomplete_features)]
36

@@ -6,7 +9,9 @@
69
struct T;
710

811
impl T {
9-
type This = Self::This; //~ ERROR overflow evaluating associated type `T::This`
12+
type This = Self::This;
13+
//[current]~^ ERROR overflow evaluating associated type `T::This`
14+
//[next]~^^ ERROR type mismatch resolving `T::This normalizes-to _`
1015
}
1116

1217
fn main() {}

tests/ui/auto-traits/assoc-ty.next.stderr

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,15 @@ LL | let _: <() as Trait>::Output = ();
3535
|
3636
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
3737

38-
error: aborting due to 4 previous errors
38+
error[E0271]: type mismatch resolving `<() as Trait>::Output normalizes-to _`
39+
--> $DIR/assoc-ty.rs:15:12
40+
|
41+
LL | let _: <() as Trait>::Output = ();
42+
| ^^^^^^^^^^^^^^^^^^^^^ types differ
43+
|
44+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
45+
46+
error: aborting due to 5 previous errors
3947

4048
Some errors have detailed explanations: E0271, E0380, E0658.
4149
For more information about an error, try `rustc --explain E0271`.

tests/ui/auto-traits/assoc-ty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ fn main() {
1616
//[current]~^ ERROR mismatched types
1717
//[next]~^^ ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _`
1818
//[next]~| ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _`
19+
//[next]~| ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _`
1920
}

tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@ help: this trait has no implementations, consider adding one
1818
|
1919
LL | trait Foo {}
2020
| ^^^^^^^^^
21-
note: required by a bound in `A`
22-
--> $DIR/alias-bounds-when-not-wf.rs:8:11
23-
|
24-
LL | type A<T: Foo> = T;
25-
| ^^^ required by this bound in `A`
2621

2722
error[E0277]: the trait bound `usize: Foo` is not satisfied
2823
--> $DIR/alias-bounds-when-not-wf.rs:16:10

0 commit comments

Comments
 (0)