Skip to content

Type parameters that appear in a fn type should not require a Send bound #2992

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

Closed
nikomatsakis opened this issue Jul 22, 2012 · 15 comments
Closed
Labels
A-lifetimes Area: Lifetimes / regions

Comments

@nikomatsakis
Copy link
Contributor

For ifaces, we enforce three criteria to ensure that regions do not escape. For fn types, we have a more simplistic requirement. This should be fixed.

Related: #2991

@graydon
Copy link
Contributor

graydon commented Dec 18, 2012

Is this still live? Can you reproduce?

@jesse99
Copy link
Contributor

jesse99 commented Dec 22, 2012

This is still required in 0.5. But note that adding Durable (or keeping the old Owned) doesn't always clue the compiler in. Here is a test case:

// rustc --test funops.rs
extern mod std;

pub type Parser<T: Copy Durable> = fn@ (State) -> Status<T>;
pub struct State {file: @~str, text: @[char], index: uint}
pub type Status<T: Copy Durable> = Result<Succeeded<T>, Failed>;
pub struct Succeeded<T: Copy Durable> {new_state: State, value: T}
pub struct Failed {old_state: State, err_state: State, mesg: @~str}

// Used to create a function that will parse self or rhs.
pub impl<T: Copy Durable> Parser<T> : ops::BitOr<Parser<T>, Parser<T>>
{
    pure fn bitor(&self, _rhs: &Parser<T>) -> Parser<T>
    {
        |input: State|
        {
            match (*self)(input)
            {
                result::Ok(ref pass1) => 
                {
                    // This is not what the real code does...
                    result::Ok(Succeeded {new_state: pass1.new_state, value: pass1.value})
                }
                result::Err(ref failure1) =>
                {
                    result::Err(Failed {old_state: input, ..*failure1})
                }
            }
        }
    }
}

// funops.rs:17:20: 17:24 error: value may contain borrowed pointers
// funops.rs:17             match (*self)(input)
//                                  ^~~~

@nikomatsakis
Copy link
Contributor Author

The reason this test case fails is that you have captured self, which is an & pointer. It is correct to complain. You would need to write: let self1 = *self outside the closure and then match self1 inside.

@nikomatsakis
Copy link
Contributor Author

@graydon it is still live.

@graydon
Copy link
Contributor

graydon commented Mar 22, 2013

non-critical for 0.6, de-milestoning

@bstrie
Copy link
Contributor

bstrie commented May 13, 2013

nmatsakis says that this is not addressed by the new borrowck. I attempted to update the test case to no avail, considering that I'm not even sure what it's supposed to demonstrate.

@nikomatsakis
Copy link
Contributor Author

That test case does not demonstrate the issue. I can make up a test case that does.

@nikomatsakis
Copy link
Contributor Author

Here is a test case:

fn enclose<A:Copy>(a: A) -> @fn() -> A {
  || copy a
}

fn main() { }

This test case should compile, but it yields an error reporting that a 'static bound is required.

@emberian
Copy link
Member

Current error message:

foo.rs:2:14: 2:15 error: cannot capture variable of type `T`, which does not fulfill `'static`, in a bounded closure
foo.rs:2       || copy a
                       ^
foo.rs:2:14: 2:15 note: this closure's environment must satisfy `'static`
foo.rs:2       || copy a
                       ^
error: aborting due to previous error

@huonw
Copy link
Member

huonw commented Sep 20, 2013

Triage: still an issue, but copy's gone:

fn enclose<A: Clone>(a: A) -> @fn() -> A {
  || a.clone()
}
fn main() {}
2992.rs:2:5: 2:6 error: cannot capture variable of type `A`, which does not fulfill `'static`, in a bounded closure
2992.rs:2   || a.clone()
               ^
2992.rs:2:5: 2:6 note: this closure's environment must satisfy `'static`
2992.rs:2   || a.clone()
               ^
error: aborting due to previous error

@nikomatsakis
Copy link
Contributor Author

Updated terminology of title. The truth is I am a bit nervous about this change -- maybe it's better to stay conservative.

@nikomatsakis
Copy link
Contributor Author

In particular we have to think carefully about variance. That said, requiring Send is definitely bogus, the right thing is 'static

@flaper87
Copy link
Contributor

This is an updated test case (since managed closures are gone):

fn enclose<A: Clone>(a: A) -> proc() -> A {
  proc() a.clone()
}
fn main() {}

@alexcrichton
Copy link
Member

Closing, this was fixed when the default bounds were removed from procedures. It is no longer required to have the Send bound.

@flaper87
Copy link
Contributor

flaper87 commented Apr 2, 2014

yay, 🍰

RalfJung pushed a commit to RalfJung/rust that referenced this issue Jul 29, 2023
celinval pushed a commit to celinval/rust-dev that referenced this issue Jun 4, 2024
Refactors the `contracts` module into several smaller modules grouped by
task. The previous modules was very long and interleaved a lot of logic
for various parts of the contracts state machine. This refactoring
groups functions by specificity, task correlation and reusability.

All code changes here are exclusively moves with no changes to
functionality.

The split is as follows:

- `mod.rs` contains definitions of the data structures used to handle
contracts, the entry point for contract handling, as well as a
documentation overview.
- `bootstrap.rs` is the logic that initialized the central data
structures, such as the handler and the functions state
- `check.rs` is all the logic required to create the function that
checks a contract.
- `replace.rs` is all the logic required to create a function that
abstracts via contract
- `shared.rs` are Kani/contract-specific helper functions that are used
in more than one of `bootstrap`, `check` or `replace`
- `helpers.rs` are Kani/contract-independent helper functions

I was going to make the `old` PR but I shudder at the though of
appending more logic to the extremely long `contracts.rs` file so I
figured I'd split the logic real quick before adding more.

By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.

Co-authored-by: Felipe R. Monteiro <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lifetimes Area: Lifetimes / regions
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants