forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of rust-lang#110204 - compiler-errors:new-solver-hir-typec…
…k-hacks, r=lcnr Deal with unnormalized projections when structurally resolving types with new solver 1. Normalize types in `structurally_resolved_type` when the new solver is enabled 2. Normalize built-in autoderef targets in `Autoderef` when the new solver is enabled 3. Normalize-erasing-regions in `resolve_type` in writeback This is motivated by the UI test provided, which currently fails with: ``` error[E0609]: no field `x` on type `<usize as SliceIndex<[Foo]>>::Output` --> <source>:9:11 | 9 | xs[0].x = 1; | ^ ``` I'm pretty happy with the approach in (1.) and (2.) and think we'll inevitably need something like this in the long-term, but (3.) seems like a hack to me. It's a *lot* of work to add tons of new calls to every user of these typeck results though (mir build, late lints, etc). Happy to discuss further. r? `@lcnr`
- Loading branch information
Showing
7 changed files
with
196 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
compiler/rustc_trait_selection/src/traits/structural_normalize.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
use rustc_infer::infer::at::At; | ||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; | ||
use rustc_infer::traits::{FulfillmentError, TraitEngine}; | ||
use rustc_middle::ty::{self, Ty}; | ||
|
||
use crate::traits::{query::evaluate_obligation::InferCtxtExt, NormalizeExt, Obligation}; | ||
|
||
pub trait StructurallyNormalizeExt<'tcx> { | ||
fn structurally_normalize( | ||
&self, | ||
ty: Ty<'tcx>, | ||
fulfill_cx: &mut dyn TraitEngine<'tcx>, | ||
) -> Result<Ty<'tcx>, Vec<FulfillmentError<'tcx>>>; | ||
} | ||
|
||
impl<'tcx> StructurallyNormalizeExt<'tcx> for At<'_, 'tcx> { | ||
fn structurally_normalize( | ||
&self, | ||
mut ty: Ty<'tcx>, | ||
fulfill_cx: &mut dyn TraitEngine<'tcx>, | ||
) -> Result<Ty<'tcx>, Vec<FulfillmentError<'tcx>>> { | ||
assert!(!ty.is_ty_var(), "should have resolved vars before calling"); | ||
|
||
if self.infcx.tcx.trait_solver_next() { | ||
while let ty::Alias(ty::Projection, projection_ty) = *ty.kind() { | ||
let new_infer_ty = self.infcx.next_ty_var(TypeVariableOrigin { | ||
kind: TypeVariableOriginKind::NormalizeProjectionType, | ||
span: self.cause.span, | ||
}); | ||
let obligation = Obligation::new( | ||
self.infcx.tcx, | ||
self.cause.clone(), | ||
self.param_env, | ||
ty::Binder::dummy(ty::ProjectionPredicate { | ||
projection_ty, | ||
term: new_infer_ty.into(), | ||
}), | ||
); | ||
if self.infcx.predicate_may_hold(&obligation) { | ||
fulfill_cx.register_predicate_obligation(self.infcx, obligation); | ||
let errors = fulfill_cx.select_where_possible(self.infcx); | ||
if !errors.is_empty() { | ||
return Err(errors); | ||
} | ||
ty = self.infcx.resolve_vars_if_possible(new_infer_ty); | ||
} else { | ||
break; | ||
} | ||
} | ||
Ok(ty) | ||
} else { | ||
Ok(self.normalize(ty).into_value_registering_obligations(self.infcx, fulfill_cx)) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// compile-flags: -Ztrait-solver=next | ||
// check-pass | ||
|
||
// Verify that we can assemble inherent impl candidates on a possibly | ||
// unnormalized self type. | ||
|
||
trait Foo { | ||
type Assoc; | ||
} | ||
impl Foo for i32 { | ||
type Assoc = Bar; | ||
} | ||
|
||
struct Bar; | ||
impl Bar { | ||
fn method(&self) {} | ||
} | ||
|
||
fn build<T: Foo>(_: T) -> T::Assoc { | ||
todo!() | ||
} | ||
|
||
fn main() { | ||
build(1i32).method(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// compile-flags: -Ztrait-solver=next | ||
// check-pass | ||
|
||
#[derive(Default)] | ||
struct Foo { | ||
x: i32, | ||
} | ||
|
||
fn main() { | ||
let mut xs = <[Foo; 1]>::default(); | ||
xs[0].x = 1; | ||
(&mut xs[0]).x = 2; | ||
} |