fix struct path

This commit is contained in:
Ali MJ Al-Nasrawy 2022-10-31 11:45:11 +03:00
parent 34329d6f6c
commit be5a45d392
8 changed files with 137 additions and 48 deletions

View File

@ -4134,6 +4134,7 @@ dependencies = [
name = "rustc_hir_typeck"
version = "0.1.0"
dependencies = [
"either",
"rustc_ast",
"rustc_data_structures",
"rustc_errors",

View File

@ -8,6 +8,7 @@ edition = "2021"
[dependencies]
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
tracing = "0.1"
either = "1.5.0"
rustc_ast = { path = "../rustc_ast" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }

View File

@ -32,6 +32,8 @@ use rustc_span::symbol::{kw, Ident};
use rustc_span::{self, sym, Span};
use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
use either::Either;
use std::iter;
use std::mem;
use std::ops::ControlFlow;
@ -1231,28 +1233,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
return None;
}
Res::Def(DefKind::Variant, _) => match ty.normalized.kind() {
ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did(), substs)),
Res::Def(DefKind::Variant, _) => match (ty.raw.kind(), ty.normalized.kind()) {
(ty::Adt(adt, substs), _) => {
Some((adt.variant_of_res(def), adt.did(), substs, Either::Left(substs)))
}
(_, ty::Adt(adt, substs)) => {
Some((adt.variant_of_res(def), adt.did(), substs, Either::Right(ty.raw)))
}
_ => bug!("unexpected type: {:?}", ty.normalized),
},
Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
| Res::SelfTyParam { .. }
| Res::SelfTyAlias { .. } => match ty.normalized.kind() {
ty::Adt(adt, substs) if !adt.is_enum() => {
Some((adt.non_enum_variant(), adt.did(), substs))
| Res::SelfTyAlias { .. } => match (ty.raw.kind(), ty.normalized.kind()) {
(ty::Adt(adt, substs), _) if !adt.is_enum() => {
Some((adt.non_enum_variant(), adt.did(), substs, Either::Left(substs)))
}
(_, ty::Adt(adt, substs)) if !adt.is_enum() => {
Some((adt.non_enum_variant(), adt.did(), substs, Either::Right(ty.raw)))
}
_ => None,
},
_ => bug!("unexpected definition: {:?}", def),
};
if let Some((variant, did, substs)) = variant {
if let Some((variant, did, substs, user_annotation)) = variant {
debug!("check_struct_path: did={:?} substs={:?}", did, substs);
// FIXME(aliemjay): We're using UserSelfTy unconditionally here because it is the only
// way to register the raw user ty, because `substs` is normalized.
let self_ty = ty::UserSelfTy { impl_def_id: did, self_ty: ty.raw };
self.write_user_type_annotation_from_substs(hir_id, did, substs, Some(self_ty));
// Register type annotation.
self.probe(|_| {
// UserSubsts and UserSelfTy are mutually exclusive here.
let (user_substs, self_ty) = match user_annotation {
Either::Left(substs) => (*substs, None),
Either::Right(self_ty) => {
(self.fresh_substs_for_item(path_span, did), Some(self_ty))
}
};
let self_ty = self_ty.map(|self_ty| ty::UserSelfTy { impl_def_id: did, self_ty });
self.write_user_type_annotation_from_substs(hir_id, did, user_substs, self_ty);
});
// Check bounds on type arguments used in the path.
self.add_required_obligations_for_hir(path_span, did, substs, hir_id);

View File

@ -1,8 +1,4 @@
//~ ERROR broken MIR
// known-bug
// failure-status: 101
// rustc-env: RUSTC_BACKTRACE=0
// check-pass
#![feature(adt_const_params, generic_const_exprs)]
#![allow(incomplete_features)]

View File

@ -11,10 +11,8 @@ struct SomeStruct<T> { t: T }
#[rustc_dump_user_substs]
fn main() {
SomeStruct { t: 22 }; // Nothing given, no annotation.
//~^ ERROR SomeStruct<^0>
SomeStruct::<_> { t: 22 }; // Nothing interesting given, no annotation.
//~^ ERROR SomeStruct<^0>
SomeStruct::<u32> { t: 22 }; // No lifetime bounds given.

View File

@ -1,20 +1,8 @@
error: user substs: UserSubsts { substs: [^0], user_self_ty: Some(UserSelfTy { impl_def_id: DefId(0:3 ~ dump_adt_brace_struct[4679]::SomeStruct), self_ty: SomeStruct<^0> }) }
--> $DIR/dump-adt-brace-struct.rs:13:5
|
LL | SomeStruct { t: 22 }; // Nothing given, no annotation.
| ^^^^^^^^^^^^^^^^^^^^
error: user substs: UserSubsts { substs: [^0], user_self_ty: Some(UserSelfTy { impl_def_id: DefId(0:3 ~ dump_adt_brace_struct[4679]::SomeStruct), self_ty: SomeStruct<^0> }) }
--> $DIR/dump-adt-brace-struct.rs:16:5
|
LL | SomeStruct::<_> { t: 22 }; // Nothing interesting given, no annotation.
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: user substs: UserSubsts { substs: [&ReStatic u32], user_self_ty: Some(UserSelfTy { impl_def_id: DefId(0:3 ~ dump_adt_brace_struct[4679]::SomeStruct), self_ty: SomeStruct<&ReStatic u32> }) }
--> $DIR/dump-adt-brace-struct.rs:21:5
error: user substs: UserSubsts { substs: [&ReStatic u32], user_self_ty: None }
--> $DIR/dump-adt-brace-struct.rs:19:5
|
LL | SomeStruct::<&'static u32> { t: &22 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
error: aborting due to previous error

View File

@ -24,6 +24,7 @@ enum MyTy<T> {
impl<T> MyTy<T> {
fn method<X>() {}
fn method2<X>(&self) {}
}
type Ty<'a> = <&'a () as Trait>::Assoc;
@ -45,6 +46,9 @@ fn test_path<'a, 'b, 'c, 'd>() {
//~^ ERROR lifetime may not live long enough
<Ty<'static>>::method::<Ty<'b>>;
//~^ ERROR lifetime may not live long enough
MyTy::Unit::<Ty<'c>>;
//~^ ERROR lifetime may not live long enough
}
fn test_call<'a, 'b, 'c>() {
@ -55,7 +59,7 @@ fn test_call<'a, 'b, 'c>() {
}
fn test_variants<'a, 'b, 'c>() {
<Ty<'a>>::Struct {}; //TODO
<Ty<'a>>::Struct {};
//~^ ERROR lifetime may not live long enough
<Ty<'b>>::Tuple();
//~^ ERROR lifetime may not live long enough
@ -63,6 +67,36 @@ fn test_variants<'a, 'b, 'c>() {
//~^ ERROR lifetime may not live long enough
}
fn test_method_call<'a>(x: MyTy<()>) {
// FIXME This should fail.
x.method2::<Ty<'a>>();
}
fn test_struct_path<'a, 'b, 'c, 'd>() {
struct Struct<T> { x: Option<T>, }
trait Project {
type Struct;
type Enum;
}
impl<T> Project for T {
type Struct = Struct<()>;
type Enum = MyTy<()>;
}
// Resolves to enum variant
MyTy::<Ty<'a>>::Struct {}; // without SelfTy
//~^ ERROR lifetime may not live long enough
<Ty<'b> as Project>::Enum::Struct {}; // with SelfTy
//~^ ERROR lifetime may not live long enough
// Resolves to struct and associated type respectively
Struct::<Ty<'c>> { x: None, }; // without SelfTy
//~^ ERROR lifetime may not live long enough
<Ty<'d> as Project>::Struct { x: None, }; // with SelfTy
//~^ ERROR lifetime may not live long enough
}
fn test_pattern<'a, 'b, 'c>() {
use MyTy::*;
match MyTy::Unit {

View File

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:32:12
--> $DIR/normalization-2.rs:33:12
|
LL | fn test_local<'a>() {
| -- lifetime `'a` defined here
@ -7,7 +7,7 @@ LL | let _: Ty<'a> = MyTy::Unit;
| ^^^^^^ requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:37:6
--> $DIR/normalization-2.rs:38:6
|
LL | fn test_closure_sig<'a, 'b>() {
| -- lifetime `'a` defined here
@ -15,7 +15,7 @@ LL | |_: Ty<'a>| {};
| ^ requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:39:11
--> $DIR/normalization-2.rs:40:11
|
LL | fn test_closure_sig<'a, 'b>() {
| -- lifetime `'b` defined here
@ -29,7 +29,7 @@ help: the following changes may resolve your lifetime errors
= help: replace `'b` with `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:44:5
--> $DIR/normalization-2.rs:45:5
|
LL | fn test_path<'a, 'b, 'c, 'd>() {
| -- lifetime `'a` defined here
@ -37,7 +37,7 @@ LL | <Ty<'a>>::method::<Ty<'static>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:46:5
--> $DIR/normalization-2.rs:47:5
|
LL | fn test_path<'a, 'b, 'c, 'd>() {
| -- lifetime `'b` defined here
@ -45,13 +45,23 @@ LL | fn test_path<'a, 'b, 'c, 'd>() {
LL | <Ty<'static>>::method::<Ty<'b>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:50:5
|
LL | fn test_path<'a, 'b, 'c, 'd>() {
| -- lifetime `'c` defined here
...
LL | MyTy::Unit::<Ty<'c>>;
| ^^^^^^^^^^^^^^^^^^^^ requires that `'c` must outlive `'static`
help: the following changes may resolve your lifetime errors
|
= help: replace `'a` with `'static`
= help: replace `'b` with `'static`
= help: replace `'c` with `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:51:5
--> $DIR/normalization-2.rs:55:5
|
LL | fn test_call<'a, 'b, 'c>() {
| -- lifetime `'a` defined here
@ -59,7 +69,7 @@ LL | <Ty<'a>>::method::<Ty<'static>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:53:5
--> $DIR/normalization-2.rs:57:5
|
LL | fn test_call<'a, 'b, 'c>() {
| -- lifetime `'b` defined here
@ -73,15 +83,15 @@ help: the following changes may resolve your lifetime errors
= help: replace `'b` with `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:58:5
--> $DIR/normalization-2.rs:62:5
|
LL | fn test_variants<'a, 'b, 'c>() {
| -- lifetime `'a` defined here
LL | <Ty<'a>>::Struct {}; //TODO
LL | <Ty<'a>>::Struct {};
| ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:60:5
--> $DIR/normalization-2.rs:64:5
|
LL | fn test_variants<'a, 'b, 'c>() {
| -- lifetime `'b` defined here
@ -90,7 +100,7 @@ LL | <Ty<'b>>::Tuple();
| ^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:62:5
--> $DIR/normalization-2.rs:66:5
|
LL | fn test_variants<'a, 'b, 'c>() {
| -- lifetime `'c` defined here
@ -105,7 +115,50 @@ help: the following changes may resolve your lifetime errors
= help: replace `'c` with `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:69:9
--> $DIR/normalization-2.rs:88:5
|
LL | fn test_struct_path<'a, 'b, 'c, 'd>() {
| -- lifetime `'a` defined here
...
LL | MyTy::<Ty<'a>>::Struct {}; // without SelfTy
| ^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:90:5
|
LL | fn test_struct_path<'a, 'b, 'c, 'd>() {
| -- lifetime `'b` defined here
...
LL | <Ty<'b> as Project>::Enum::Struct {}; // with SelfTy
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:94:5
|
LL | fn test_struct_path<'a, 'b, 'c, 'd>() {
| -- lifetime `'c` defined here
...
LL | Struct::<Ty<'c>> { x: None, }; // without SelfTy
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'c` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:96:5
|
LL | fn test_struct_path<'a, 'b, 'c, 'd>() {
| -- lifetime `'d` defined here
...
LL | <Ty<'d> as Project>::Struct { x: None, }; // with SelfTy
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'d` must outlive `'static`
help: the following changes may resolve your lifetime errors
|
= help: replace `'a` with `'static`
= help: replace `'b` with `'static`
= help: replace `'c` with `'static`
= help: replace `'d` with `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:103:9
|
LL | fn test_pattern<'a, 'b, 'c>() {
| -- lifetime `'a` defined here
@ -114,7 +167,7 @@ LL | Struct::<Ty<'a>> {..} => {},
| ^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:71:9
--> $DIR/normalization-2.rs:105:9
|
LL | fn test_pattern<'a, 'b, 'c>() {
| -- lifetime `'b` defined here
@ -123,7 +176,7 @@ LL | Tuple::<Ty<'b>> (..) => {},
| ^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:73:9
--> $DIR/normalization-2.rs:107:9
|
LL | fn test_pattern<'a, 'b, 'c>() {
| -- lifetime `'c` defined here
@ -137,5 +190,5 @@ help: the following changes may resolve your lifetime errors
= help: replace `'b` with `'static`
= help: replace `'c` with `'static`
error: aborting due to 13 previous errors
error: aborting due to 18 previous errors