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

Refactoring TyBox -> TyAdt #39230

Merged
merged 4 commits into from
Jan 31, 2017
Merged

Refactoring TyBox -> TyAdt #39230

merged 4 commits into from
Jan 31, 2017

Conversation

petrochenkov
Copy link
Contributor

@petrochenkov
Copy link
Contributor Author

petrochenkov commented Jan 21, 2017

The largest area where Box is still special is various layout calculations and translation, I haven't touched anything of it. I believe all of it can be done uniformly with normal structs.
There's also drop translation. I'm not sure it can be completely moved into the library given that Box is piece-by-piece movable, but it may be possible to move at least deallocation with some remaining compiler support.
All the remaining special-ness is borrowck stuff and unsizing coercions + box expressions and patterns.

self.walk_cast(cast_expr, from_referent_ty, to_referent_ty);
/*From:*/ (&ty::TyAdt(from_def, _),
/*To: */ &ty::TyAdt(to_def, _)) if from_def.is_box() && to_def.is_box() => {
self.walk_cast(cast_expr, from_ty.boxed_ty(), to_ty.boxed_ty());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nikomatsakis Why is this special-casing Box<T>?

@@ -3486,7 +3486,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
hir::ExprBox(ref subexpr) => {
let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
match ty.sty {
ty::TyBox(ty) => Expectation::rvalue_hint(self, ty),
ty::TyAdt(def, _) if def.is_box()
=> Expectation::rvalue_hint(self, ty.boxed_ty()),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd have substs.type_at(0) everywhere instead of a boxed_ty method.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But of course, this may be too annoying to repeat at every single use site.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used often. A dedicated method seems to be more convenient and readable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. My next choice would be box_pointee but boxed_ty seems fine anyway.

// Support for TyBox is built-in and its drop glue is
// special. It may move to library and have Drop impl. As
// a safe-guard, assert TyBox not used with TyContents.
assert!(!skip_dtor);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we still need the assert?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assert started failing when Box got a Drop impl.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, then skip_dtor should toggle calling free (which can also be the Drop impl?).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean something like

--- a/src/librustc_trans/glue.rs
+++ b/src/librustc_trans/glue.rs
@@ -210,7 +210,7 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi
     };

     let bcx = match t.sty {
-        ty::TyAdt(def, _) if def.is_box() => {
+        ty::TyAdt(def, _) if def.is_box()  && !skip_dtor => {
             // Support for Box is built-in as yet and its drop glue is special
             // despite having a dummy Drop impl in the library.
             let content_ty = t.boxed_ty();

?

I.e. if we get here with skip_dtor == false, we generate full drop glue (including both dropping the inner type and deallocation), otherwise we generate "structural drop" only, which is noop for Box.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, what happens if full drop glue in generated in both cases? I haven't observed any regressions in tests.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be not used at all. @michaelwoerister and @arielb1 would know.
What I meant is making the trans_exchange_free_ty call conditional on !skip_dtor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've restored the previous behavior in another place (find_drop_glue_neighbors) and put this assert back.

pub fn boxed_ty(&self) -> Ty<'tcx> {
match self.sty {
TyAdt(def, substs) if def.is_box() =>
substs.types().next().expect("Box<T> doesn't have type parameters"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be substs.type_at(0).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

@@ -1322,6 +1322,7 @@ bitflags! {
const IS_SIMD = 1 << 4,
const IS_FUNDAMENTAL = 1 << 5,
const IS_UNION = 1 << 6,
const IS_BOX = 1 << 7,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems maybe a bit sketchy but it's a bit of cache so I can live with it.

@Manishearth
Copy link
Member

Manishearth commented Jan 21, 2017

I would like to eventually move the piece-by-piece movable stuff into an internal-only DerefMove. Might need to make it an unsafe trait since we may have to make assumptions about the destructor.

@eddyb
Copy link
Member

eddyb commented Jan 21, 2017

Unsizing coercions and layout go hand in hand. The problem with layout is unpacking newtypes and that's a pretty big can of worms given how LLVM "types" work, several strategical refactors are still needed there.

@petrochenkov
Copy link
Contributor Author

Rebased, comments addressed.

@eddyb
Copy link
Member

eddyb commented Jan 28, 2017

@bors r+

@bors
Copy link
Contributor

bors commented Jan 28, 2017

📌 Commit 8d36b1c has been approved by eddyb

@bors
Copy link
Contributor

bors commented Jan 28, 2017

⌛ Testing commit 8d36b1c with merge 4065356...

@bors
Copy link
Contributor

bors commented Jan 28, 2017

💔 Test failed - status-appveyor

@bors
Copy link
Contributor

bors commented Jan 28, 2017

☔ The latest upstream changes (presumably #39305) made this pull request unmergeable. Please resolve the merge conflicts.

@petrochenkov
Copy link
Contributor Author

I can't reproduce the Appveyor failure locally. Let's try again.
@bors r=eddyb

@bors
Copy link
Contributor

bors commented Jan 28, 2017

📌 Commit f6be8fa has been approved by eddyb

@bors
Copy link
Contributor

bors commented Jan 28, 2017

⌛ Testing commit f6be8fa with merge c3dec74...

@bors
Copy link
Contributor

bors commented Jan 28, 2017

💔 Test failed - status-appveyor

@petrochenkov
Copy link
Contributor Author

I still can't reproduce this assert with all debug and assert options enabled.
The assert doesn't also happen when I use exactly the options used by Appveyor (modulo --enable-sccache).

@alexcrichton
What version of LLVM is used by Appveyor ?
How is it possible for the LLVM assert to fire on Appveyor while LLVM asserts are not enabled there?

@petrochenkov
Copy link
Contributor Author

The assert is about MSVC debuginfo:

Assertion failed: !isa<DIType>(Scope) && "shouldn't make a namespace scope for a type", file C:\projects\rust\src\llvm\lib\CodeGen\AsmPrinter\CodeViewDebug.cpp, line 202

@michaelwoerister Maybe you have ideas what part of this PR could do this?

@alexcrichton
Copy link
Member

@petrochenkov it should be whatever the llvm submodule is, but maybe a stale version is cached? You could try touching the llvm trigger and re-send to bors to see if a fresh compile works?

@petrochenkov
Copy link
Contributor Author

@bors r=eddyb

@bors
Copy link
Contributor

bors commented Jan 28, 2017

📌 Commit 468a79d has been approved by eddyb

@bors
Copy link
Contributor

bors commented Jan 28, 2017

⌛ Testing commit 468a79d with merge a576531...

@bors
Copy link
Contributor

bors commented Jan 28, 2017

💔 Test failed - status-appveyor

@petrochenkov
Copy link
Contributor Author

Phew, reproduced locally.

@michaelwoerister
Copy link
Member

Maybe you have ideas what part of this PR could do this?

I don't see any obvious place. Maybe you could instrument your LLVM to print out which Scope it's complaining about?

@petrochenkov
Copy link
Contributor Author

@michaelwoerister

directory:
filename:
name: Box<std::error::{{impl}}::from::StringError>

@petrochenkov
Copy link
Contributor Author

Found it.

diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs
index f05d48566d..e9468e5663 100644
--- a/src/librustc_trans/debuginfo/mod.rs
+++ b/src/librustc_trans/debuginfo/mod.rs
@@ -400,7 +400,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 // Only "class" methods are generally understood by LLVM,
                 // so avoid methods on other types (e.g. `<*mut T>::null`).
                 match impl_self_ty.sty {
-                    ty::TyAdt(..) => {
+                    ty::TyAdt(def, ..) if !def.is_box() => {
                         Some(type_metadata(cx, impl_self_ty, syntax_pos::DUMMY_SP))
                     }
                     _ => None

@petrochenkov
Copy link
Contributor Author

@bors r=eddyb

@bors
Copy link
Contributor

bors commented Jan 30, 2017

📌 Commit 93e3f63 has been approved by eddyb

@bors
Copy link
Contributor

bors commented Jan 31, 2017

⌛ Testing commit 93e3f63 with merge 8e9e055...

bors added a commit that referenced this pull request Jan 31, 2017
@bors
Copy link
Contributor

bors commented Jan 31, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: eddyb
Pushing 8e9e055 to master...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants