Rollup merge of #113217 - ericmarkmartin:lower-type-relative-ctor-to-adt, r=cjgillot

resolve typerelative ctors to adt

Associated issue: #110508

r? ``@spastorino``
This commit is contained in:
Matthias Krüger 2023-07-08 20:53:29 +02:00 committed by GitHub
commit b637be7a17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 530 additions and 17 deletions

View File

@ -215,17 +215,18 @@ impl<'tcx> Cx<'tcx> {
// so we wouldn't have to compute and store the actual value
let hir::ExprKind::Path(ref qpath) = source.kind else {
return ExprKind::Cast { source: self.mirror_expr(source)};
return ExprKind::Cast { source: self.mirror_expr(source) };
};
let res = self.typeck_results().qpath_res(qpath, source.hir_id);
let ty = self.typeck_results().node_type(source.hir_id);
let ty::Adt(adt_def, substs) = ty.kind() else {
return ExprKind::Cast { source: self.mirror_expr(source)};
return ExprKind::Cast { source: self.mirror_expr(source) };
};
let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res else {
return ExprKind::Cast { source: self.mirror_expr(source)};
let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res
else {
return ExprKind::Cast { source: self.mirror_expr(source) };
};
let idx = adt_def.variant_index_with_ctor_id(variant_ctor_id);
@ -358,19 +359,35 @@ impl<'tcx> Cx<'tcx> {
});
}
}
let adt_data =
if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = fun.kind {
// Tuple-like ADTs are represented as ExprKind::Call. We convert them here.
expr_ty.ty_adt_def().and_then(|adt_def| match path.res {
Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => {
Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
// Tuple-like ADTs are represented as ExprKind::Call. We convert them here.
let adt_data = if let hir::ExprKind::Path(ref qpath) = fun.kind
&& let Some(adt_def) = expr_ty.ty_adt_def() {
match qpath {
hir::QPath::Resolved(_, ref path) => {
match path.res {
Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => {
Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
}
Res::SelfCtor(..) => Some((adt_def, FIRST_VARIANT)),
_ => None,
}
Res::SelfCtor(..) => Some((adt_def, FIRST_VARIANT)),
_ => None,
})
} else {
None
};
}
hir::QPath::TypeRelative(_ty, _) => {
if let Some((DefKind::Ctor(_, CtorKind::Fn), ctor_id)) =
self.typeck_results().type_dependent_def(fun.hir_id)
{
Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
} else {
None
}
}
_ => None,
}
} else {
None
};
if let Some((adt_def, index)) = adt_data {
let substs = self.typeck_results().node_substs(fun.hir_id);
let user_provided_types = self.typeck_results().user_provided_types();

View File

@ -0,0 +1,13 @@
// EMIT_MIR issue_110508.{impl#0}-BAR.built.after.mir
// EMIT_MIR issue_110508.{impl#0}-SELF_BAR.built.after.mir
enum Foo {
Bar(()),
}
impl Foo {
const BAR: Foo = Foo::Bar(());
const SELF_BAR: Foo = Self::Bar(());
}
fn main() {}

View File

@ -0,0 +1,14 @@
// MIR for `<impl at $DIR/issue_110508.rs:8:1: 8:9>::BAR` after built
const <impl at $DIR/issue_110508.rs:8:1: 8:9>::BAR: Foo = {
let mut _0: Foo;
let mut _1: ();
bb0: {
StorageLive(_1);
_1 = ();
_0 = Foo::Bar(move _1);
StorageDead(_1);
return;
}
}

View File

@ -0,0 +1,14 @@
// MIR for `<impl at $DIR/issue_110508.rs:8:1: 8:9>::SELF_BAR` after built
const <impl at $DIR/issue_110508.rs:8:1: 8:9>::SELF_BAR: Foo = {
let mut _0: Foo;
let mut _1: ();
bb0: {
StorageLive(_1);
_1 = ();
_0 = Foo::Bar(move _1);
StorageDead(_1);
return;
}
}

View File

@ -147,7 +147,7 @@ LL | fn test_variants<'a, 'b, 'c>() {
| -- lifetime `'b` defined here
...
LL | <Ty<'b>>::Tuple();
| ^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
| ^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/normalization-2.rs:93:5

View File

@ -0,0 +1,38 @@
// run-pass
#[derive(PartialEq, Eq)]
pub enum Foo {
FooA(()),
FooB(Vec<()>),
}
impl Foo {
const A1: Foo = Foo::FooA(());
const A2: Foo = Self::FooA(());
const A3: Self = Foo::FooA(());
const A4: Self = Self::FooA(());
}
fn main() {
let foo = Foo::FooA(());
match foo {
Foo::A1 => {},
_ => {},
}
match foo {
Foo::A2 => {},
_ => {},
}
match foo {
Foo::A3 => {},
_ => {},
}
match foo {
Foo::A4 => {},
_ => {},
}
}

View File

@ -0,0 +1,18 @@
// compile-flags: -Z unpretty=thir-flat
// check-pass
// Previously, the constants with `Self::Bar(())` would be `Call`s instead of
// `Adt`s in THIR.
pub enum Foo {
Bar(()),
}
impl Foo {
const BAR1: Foo = Foo::Bar(());
const BAR2: Foo = Self::Bar(());
const BAR3: Self = Foo::Bar(());
const BAR4: Self = Self::Bar(());
}
fn main() {}

View File

@ -0,0 +1,399 @@
DefId(0:8 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR1):
Thir {
body_type: Const(
Foo,
),
arms: [],
blocks: [],
exprs: [
Expr {
kind: Tuple {
fields: [],
},
ty: (),
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:12:32: 12:34 (#0),
},
Expr {
kind: Scope {
region_scope: Node(7),
lint_level: Explicit(
HirId(DefId(0:8 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR1).7),
),
value: e0,
},
ty: (),
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:12:32: 12:34 (#0),
},
Expr {
kind: Adt(
AdtExpr {
adt_def: Foo,
variant_index: 0,
substs: [],
user_ty: None,
fields: [
FieldExpr {
name: 0,
expr: e1,
},
],
base: None,
},
),
ty: Foo,
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:12:23: 12:35 (#0),
},
Expr {
kind: Scope {
region_scope: Node(3),
lint_level: Explicit(
HirId(DefId(0:8 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR1).3),
),
value: e2,
},
ty: Foo,
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:12:23: 12:35 (#0),
},
Expr {
kind: Scope {
region_scope: Destruction(3),
lint_level: Inherited,
value: e3,
},
ty: Foo,
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:12:23: 12:35 (#0),
},
],
stmts: [],
params: [],
}
DefId(0:9 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR2):
Thir {
body_type: Const(
Foo,
),
arms: [],
blocks: [],
exprs: [
Expr {
kind: Tuple {
fields: [],
},
ty: (),
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:13:33: 13:35 (#0),
},
Expr {
kind: Scope {
region_scope: Node(8),
lint_level: Explicit(
HirId(DefId(0:9 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR2).8),
),
value: e0,
},
ty: (),
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:13:33: 13:35 (#0),
},
Expr {
kind: Adt(
AdtExpr {
adt_def: Foo,
variant_index: 0,
substs: [],
user_ty: None,
fields: [
FieldExpr {
name: 0,
expr: e1,
},
],
base: None,
},
),
ty: Foo,
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:13:23: 13:36 (#0),
},
Expr {
kind: Scope {
region_scope: Node(3),
lint_level: Explicit(
HirId(DefId(0:9 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR2).3),
),
value: e2,
},
ty: Foo,
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:13:23: 13:36 (#0),
},
Expr {
kind: Scope {
region_scope: Destruction(3),
lint_level: Inherited,
value: e3,
},
ty: Foo,
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:13:23: 13:36 (#0),
},
],
stmts: [],
params: [],
}
DefId(0:10 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR3):
Thir {
body_type: Const(
Foo,
),
arms: [],
blocks: [],
exprs: [
Expr {
kind: Tuple {
fields: [],
},
ty: (),
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:14:33: 14:35 (#0),
},
Expr {
kind: Scope {
region_scope: Node(7),
lint_level: Explicit(
HirId(DefId(0:10 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR3).7),
),
value: e0,
},
ty: (),
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:14:33: 14:35 (#0),
},
Expr {
kind: Adt(
AdtExpr {
adt_def: Foo,
variant_index: 0,
substs: [],
user_ty: None,
fields: [
FieldExpr {
name: 0,
expr: e1,
},
],
base: None,
},
),
ty: Foo,
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:14:24: 14:36 (#0),
},
Expr {
kind: Scope {
region_scope: Node(3),
lint_level: Explicit(
HirId(DefId(0:10 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR3).3),
),
value: e2,
},
ty: Foo,
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:14:24: 14:36 (#0),
},
Expr {
kind: Scope {
region_scope: Destruction(3),
lint_level: Inherited,
value: e3,
},
ty: Foo,
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:14:24: 14:36 (#0),
},
],
stmts: [],
params: [],
}
DefId(0:11 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR4):
Thir {
body_type: Const(
Foo,
),
arms: [],
blocks: [],
exprs: [
Expr {
kind: Tuple {
fields: [],
},
ty: (),
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:15:34: 15:36 (#0),
},
Expr {
kind: Scope {
region_scope: Node(8),
lint_level: Explicit(
HirId(DefId(0:11 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR4).8),
),
value: e0,
},
ty: (),
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:15:34: 15:36 (#0),
},
Expr {
kind: Adt(
AdtExpr {
adt_def: Foo,
variant_index: 0,
substs: [],
user_ty: None,
fields: [
FieldExpr {
name: 0,
expr: e1,
},
],
base: None,
},
),
ty: Foo,
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:15:24: 15:37 (#0),
},
Expr {
kind: Scope {
region_scope: Node(3),
lint_level: Explicit(
HirId(DefId(0:11 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR4).3),
),
value: e2,
},
ty: Foo,
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:15:24: 15:37 (#0),
},
Expr {
kind: Scope {
region_scope: Destruction(3),
lint_level: Inherited,
value: e3,
},
ty: Foo,
temp_lifetime: Some(
Node(3),
),
span: $DIR/thir-flat-const-variant.rs:15:24: 15:37 (#0),
},
],
stmts: [],
params: [],
}
DefId(0:12 ~ thir_flat_const_variant[1f54]::main):
Thir {
body_type: Fn(
fn(),
),
arms: [],
blocks: [
Block {
targeted_by_break: false,
region_scope: Node(1),
opt_destruction_scope: None,
span: $DIR/thir-flat-const-variant.rs:18:11: 18:13 (#0),
stmts: [],
expr: None,
safety_mode: Safe,
},
],
exprs: [
Expr {
kind: Block {
block: b0,
},
ty: (),
temp_lifetime: Some(
Node(2),
),
span: $DIR/thir-flat-const-variant.rs:18:11: 18:13 (#0),
},
Expr {
kind: Scope {
region_scope: Node(2),
lint_level: Explicit(
HirId(DefId(0:12 ~ thir_flat_const_variant[1f54]::main).2),
),
value: e0,
},
ty: (),
temp_lifetime: Some(
Node(2),
),
span: $DIR/thir-flat-const-variant.rs:18:11: 18:13 (#0),
},
Expr {
kind: Scope {
region_scope: Destruction(2),
lint_level: Inherited,
value: e1,
},
ty: (),
temp_lifetime: Some(
Node(2),
),
span: $DIR/thir-flat-const-variant.rs:18:11: 18:13 (#0),
},
],
stmts: [],
params: [],
}