mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
IAT: Reinstate early bailout
This commit is contained in:
@@ -1481,11 +1481,8 @@ fn probe_inherent_assoc_item(
|
||||
match assoc_tag {
|
||||
// Don't attempt to look up inherent associated types when the feature is not
|
||||
// enabled. Theoretically it'd be fine to do so since we feature-gate their
|
||||
// definition site. However, due to current limitations of the implementation
|
||||
// (caused by us performing selection during HIR ty lowering instead of in the
|
||||
// trait solver), IATs can lead to cycle errors (#108491) which mask the
|
||||
// feature-gate error, needlessly confusing users who use IATs by accident
|
||||
// (#113265).
|
||||
// definition site. However, the current implementation of inherent associated
|
||||
// items is somewhat brittle, so let's not run it by default.
|
||||
ty::AssocTag::Type => return Ok(None),
|
||||
ty::AssocTag::Const => {
|
||||
// We also gate the mgca codepath for type-level uses of inherent consts
|
||||
@@ -1514,9 +1511,18 @@ fn probe_inherent_assoc_item(
|
||||
})
|
||||
.collect();
|
||||
|
||||
// At the moment, we actually bail out with a hard error if the selection of an inherent
|
||||
// associated item fails (see below). This means we never consider trait associated items
|
||||
// as potential fallback candidates (#142006). To temporarily mask that issue, let's not
|
||||
// select at all if there are no early inherent candidates.
|
||||
if candidates.is_empty() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let (applicable_candidates, fulfillment_errors) =
|
||||
self.select_inherent_assoc_candidates(span, self_ty, candidates.clone());
|
||||
|
||||
// FIXME(#142006): Don't eagerly error here, there might be applicable trait candidates.
|
||||
let InherentAssocCandidate { impl_, assoc_item, scope: def_scope } =
|
||||
match &applicable_candidates[..] {
|
||||
&[] => Err(self.report_unresolved_inherent_assoc_item(
|
||||
@@ -1537,6 +1543,8 @@ fn probe_inherent_assoc_item(
|
||||
)),
|
||||
}?;
|
||||
|
||||
// FIXME(#142006): Don't eagerly validate here, there might be trait candidates that are
|
||||
// accessible (visible and stable) contrary to the inherent candidate.
|
||||
self.check_assoc_item(assoc_item, name, def_scope, block, span);
|
||||
|
||||
// FIXME(fmease): Currently creating throwaway `parent_args` to please
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// Ensure that IAT selection doesn't hard error on associated type paths that could refer to
|
||||
// an inherent associated type if we can't find an applicable inherent candidate since there
|
||||
// might still be valid trait associated type candidates.
|
||||
//
|
||||
// FIXME(#142006): This only covers the bare minimum, we also need to disqualify inherent
|
||||
// candidates if they're inaccessible or if the impl headers don't match / apply.
|
||||
//
|
||||
// issue: <https://github.com/rust-lang/rust/issues/142006#issuecomment-2938846613>
|
||||
//@ check-pass
|
||||
|
||||
#![feature(inherent_associated_types)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
struct Type;
|
||||
trait Trait { type AssocTy; fn scope(); }
|
||||
|
||||
impl Trait for Type {
|
||||
type AssocTy = ();
|
||||
|
||||
fn scope() {
|
||||
let (): Self::AssocTy;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { <Type as Trait>::scope(); }
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
#![feature(inherent_associated_types)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
// Check that it's okay to report “[inherent] associated type […] not found” for inherent associated
|
||||
// type candidates that are not applicable (due to unsuitable Self type) even if there exists a
|
||||
// “shadowed” associated type from a trait with the same name since its use would be ambiguous
|
||||
// anyway if the IAT didn't exist.
|
||||
// FIXME(inherent_associated_types): Figure out which error would be more helpful here.
|
||||
|
||||
//@ revisions: shadowed uncovered
|
||||
|
||||
struct S<T>(T);
|
||||
|
||||
trait Tr {
|
||||
type Pr;
|
||||
}
|
||||
|
||||
impl<T> Tr for S<T> {
|
||||
type Pr = ();
|
||||
}
|
||||
|
||||
#[cfg(shadowed)]
|
||||
impl S<()> {
|
||||
type Pr = i32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _: S::<bool>::Pr = ();
|
||||
//[shadowed]~^ ERROR associated type `Pr` not found
|
||||
//[uncovered]~^^ ERROR associated type `Pr` not found
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
error[E0220]: associated type `Pr` not found for `S<bool>` in the current scope
|
||||
--> $DIR/not-found-self-type-differs-shadowing-trait-item.rs:28:23
|
||||
|
|
||||
LL | struct S<T>(T);
|
||||
| ----------- associated type `Pr` not found for this struct
|
||||
...
|
||||
LL | let _: S::<bool>::Pr = ();
|
||||
| ^^ associated item not found in `S<bool>`
|
||||
|
|
||||
= note: the associated type was found for
|
||||
- `S<()>`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0220`.
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
error[E0220]: associated type `Pr` not found for `S<bool>` in the current scope
|
||||
--> $DIR/not-found-self-type-differs-shadowing-trait-item.rs:28:23
|
||||
|
|
||||
LL | struct S<T>(T);
|
||||
| ----------- associated type `Pr` not found for this struct
|
||||
...
|
||||
LL | let _: S::<bool>::Pr = ();
|
||||
| ^^ associated item not found in `S<bool>`
|
||||
|
|
||||
= note: the associated type was found for
|
||||
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0220`.
|
||||
@@ -0,0 +1,28 @@
|
||||
#![feature(inherent_associated_types)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
// Ensure that prefer inherent associated types over trait associated types
|
||||
// (assuming the impl headers match and they're accessible).
|
||||
//@ check-pass
|
||||
|
||||
struct Adt;
|
||||
|
||||
impl Adt {
|
||||
type Ty = ();
|
||||
}
|
||||
|
||||
trait Trait {
|
||||
type Ty;
|
||||
fn scope();
|
||||
}
|
||||
|
||||
impl Trait for Adt {
|
||||
type Ty = i32;
|
||||
fn scope() {
|
||||
// We prefer the inherent assoc ty `Adt::Ty` (`()`) over the
|
||||
// trait assoc ty `<Adt as Trait>::Ty` (`i32`).
|
||||
let (): Self::Ty;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
Reference in New Issue
Block a user