Skip to content

Commit

Permalink
Rollup merge of rust-lang#113217 - ericmarkmartin:lower-type-relative…
Browse files Browse the repository at this point in the history
…-ctor-to-adt, r=cjgillot

resolve typerelative ctors to adt

Associated issue: rust-lang#110508

r? `@spastorino`
  • Loading branch information
matthiaskrgr committed Jul 8, 2023
2 parents a0d91e8 + 261c023 commit 8c4a459
Show file tree
Hide file tree
Showing 8 changed files with 529 additions and 16 deletions.
47 changes: 32 additions & 15 deletions compiler/rustc_mir_build/src/thir/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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) => {

// 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,
}
}
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
}
Res::SelfCtor(..) => Some((adt_def, FIRST_VARIANT)),
_ => None,
})
} 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();
Expand Down
13 changes: 13 additions & 0 deletions tests/mir-opt/building/issue_110508.rs
Original file line number Diff line number Diff line change
@@ -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() {}
14 changes: 14 additions & 0 deletions tests/mir-opt/building/issue_110508.{impl#0}-BAR.built.after.mir
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
2 changes: 1 addition & 1 deletion tests/ui/nll/user-annotations/normalization-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
38 changes: 38 additions & 0 deletions tests/ui/pattern/issue-110508.rs
Original file line number Diff line number Diff line change
@@ -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 => {},
_ => {},
}
}
18 changes: 18 additions & 0 deletions tests/ui/thir-print/thir-flat-const-variant.rs
Original file line number Diff line number Diff line change
@@ -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() {}
Loading

0 comments on commit 8c4a459

Please sign in to comment.