-
Notifications
You must be signed in to change notification settings - Fork 13k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #25113 - pnkfelix:dropck-itemless-traits, r=huonw
Generalize dropck to ignore item-less traits Fix #24805. (This is the reopened + rebased version of PR #24898)
- Loading branch information
Showing
4 changed files
with
238 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
src/test/compile-fail/issue-24805-dropck-child-has-items-via-parent.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// Check that child trait who only has items via its *parent* trait | ||
// does cause dropck to inject extra region constraints. | ||
|
||
#![allow(non_camel_case_types)] | ||
|
||
trait Parent { fn foo(&self); } | ||
trait Child: Parent { } | ||
|
||
impl Parent for i32 { fn foo(&self) { } } | ||
impl<'a> Parent for &'a D_Child<i32> { | ||
fn foo(&self) { | ||
println!("accessing child value: {}", self.0); | ||
} | ||
} | ||
|
||
impl Child for i32 { } | ||
impl<'a> Child for &'a D_Child<i32> { } | ||
|
||
struct D_Child<T:Child>(T); | ||
impl <T:Child> Drop for D_Child<T> { fn drop(&mut self) { self.0.foo() } } | ||
|
||
fn f_child() { | ||
// `_d` and `d1` are assigned the *same* lifetime by region inference ... | ||
let (_d, d1); | ||
|
||
d1 = D_Child(1); | ||
// ... we store a reference to `d1` within `_d` ... | ||
_d = D_Child(&d1); //~ ERROR `d1` does not live long enough | ||
|
||
// ... dropck *should* complain, because Drop of _d could (and | ||
// does) access the already dropped `d1` via the `foo` method. | ||
} | ||
|
||
fn main() { | ||
f_child(); | ||
} |
64 changes: 64 additions & 0 deletions
64
src/test/compile-fail/issue-24805-dropck-trait-has-items.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// Check that traits with various kinds of associated items cause | ||
// dropck to inject extra region constraints. | ||
|
||
#![allow(non_camel_case_types)] | ||
|
||
trait HasSelfMethod { fn m1(&self) { } } | ||
trait HasMethodWithSelfArg { fn m2(x: &Self) { } } | ||
trait HasType { type Something; } | ||
|
||
impl HasSelfMethod for i32 { } | ||
impl HasMethodWithSelfArg for i32 { } | ||
impl HasType for i32 { type Something = (); } | ||
|
||
impl<'a,T> HasSelfMethod for &'a T { } | ||
impl<'a,T> HasMethodWithSelfArg for &'a T { } | ||
impl<'a,T> HasType for &'a T { type Something = (); } | ||
|
||
// e.g. `impl_drop!(Send, D_Send)` expands to: | ||
// ```rust | ||
// struct D_Send<T:Send>(T); | ||
// impl<T:Send> Drop for D_Send<T> { fn drop(&mut self) { } } | ||
// ``` | ||
macro_rules! impl_drop { | ||
($Bound:ident, $Id:ident) => { | ||
struct $Id<T:$Bound>(T); | ||
impl <T:$Bound> Drop for $Id<T> { fn drop(&mut self) { } } | ||
} | ||
} | ||
|
||
impl_drop!{HasSelfMethod, D_HasSelfMethod} | ||
impl_drop!{HasMethodWithSelfArg, D_HasMethodWithSelfArg} | ||
impl_drop!{HasType, D_HasType} | ||
|
||
fn f_sm() { | ||
let (_d, d1); | ||
d1 = D_HasSelfMethod(1); | ||
_d = D_HasSelfMethod(&d1); //~ ERROR `d1` does not live long enough | ||
} | ||
fn f_mwsa() { | ||
let (_d, d1); | ||
d1 = D_HasMethodWithSelfArg(1); | ||
_d = D_HasMethodWithSelfArg(&d1); //~ ERROR `d1` does not live long enough | ||
} | ||
fn f_t() { | ||
let (_d, d1); | ||
d1 = D_HasType(1); | ||
_d = D_HasType(&d1); //~ ERROR `d1` does not live long enough | ||
} | ||
|
||
fn main() { | ||
f_sm(); | ||
f_mwsa(); | ||
f_t(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// Check that item-less traits do not cause dropck to inject extra | ||
// region constraints. | ||
|
||
#![allow(non_camel_case_types)] | ||
|
||
trait UserDefined { } | ||
|
||
impl UserDefined for i32 { } | ||
impl<'a, T> UserDefined for &'a T { } | ||
|
||
// e.g. `impl_drop!(Send, D_Send)` expands to: | ||
// ```rust | ||
// struct D_Send<T:Send>(T); | ||
// impl<T:Send> Drop for D_Send<T> { fn drop(&mut self) { } } | ||
// ``` | ||
macro_rules! impl_drop { | ||
($Bound:ident, $Id:ident) => { | ||
struct $Id<T:$Bound>(T); | ||
impl <T:$Bound> Drop for $Id<T> { fn drop(&mut self) { } } | ||
} | ||
} | ||
|
||
impl_drop!{Send, D_Send} | ||
impl_drop!{Sized, D_Sized} | ||
|
||
// See note below regarding Issue 24895 | ||
// impl_drop!{Copy, D_Copy} | ||
|
||
impl_drop!{Sync, D_Sync} | ||
impl_drop!{UserDefined, D_UserDefined} | ||
|
||
macro_rules! body { | ||
($id:ident) => { { | ||
// `_d` and `d1` are assigned the *same* lifetime by region inference ... | ||
let (_d, d1); | ||
|
||
d1 = $id(1); | ||
// ... we store a reference to `d1` within `_d` ... | ||
_d = $id(&d1); | ||
|
||
// ... a *conservative* dropck will thus complain, because it | ||
// thinks Drop of _d could access the already dropped `d1`. | ||
} } | ||
} | ||
|
||
fn f_send() { body!(D_Send) } | ||
fn f_sized() { body!(D_Sized) } | ||
fn f_sync() { body!(D_Sync) } | ||
|
||
// Issue 24895: Copy: Clone implies `impl<T:Copy> Drop for ...` can | ||
// access a user-defined clone() method, which causes this test case | ||
// to fail. | ||
// | ||
// If 24895 is resolved by removing the `Copy: Clone` relationship, | ||
// then this definition and the call below should be uncommented. If | ||
// it is resolved by deciding to keep the `Copy: Clone` relationship, | ||
// then this comment and the associated bits of code can all be | ||
// removed. | ||
|
||
// fn f_copy() { body!(D_Copy) } | ||
|
||
fn f_userdefined() { body!(D_UserDefined) } | ||
|
||
fn main() { | ||
f_send(); | ||
f_sized(); | ||
// See note above regarding Issue 24895. | ||
// f_copy(); | ||
f_sync(); | ||
f_userdefined(); | ||
} |