Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resolve typerelative ctors to adt #113217

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -208,17 +208,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 @@ -351,19 +352,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