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

borrowed pointers should be compared #3289

Closed
Vincent-Belliard opened this issue Aug 27, 2012 · 8 comments
Closed

borrowed pointers should be compared #3289

Vincent-Belliard opened this issue Aug 27, 2012 · 8 comments
Assignees
Labels
A-lifetimes Area: Lifetimes / regions
Milestone

Comments

@Vincent-Belliard
Copy link
Contributor

The following example try to compare two pointers:

fn do_cmp(a: &int, b: &int) {
io::println("do_cmp");
if a == b { io::println("same ref"); }
}

fn main() {
let a = @10;
let b = @10;
do_cmp(a, b);
do_cmp(a, a);
}

We have the following message:
try.rs:3:12: 3:13 error: mismatched types: expected &int but found &int (the anonymous lifetime #2 defined on the block at 1:28 does not necessarily outlive the anonymous lifetime #1 defined on the block at 1:28)
try.rs:3 if a == b { io::println("same ref"); }
^
error: aborting due to previous error

I think that it should compile. I think it should also compile if we have this prototype:
fn do_cmp(a: &int, b: @int)

@catamorphism
Copy link
Contributor

fn do_cmp(a: &int, b: @int)

This certainly shouldn't compile. You can't compare two things that have different types (if you really want to compare the two pointers, you can use unsafe::reinterpret_cast, but that will require you to use an unsafe block).

The first example looks like a bug, but @nikomatsakis should say for sure.

@Vincent-Belliard
Copy link
Contributor Author

I agree you can't compile with fn do_cmp(a: ~int, b: @int) because the two pointers will reference two regions of memory and the test will always be false.

However, we can pass a shared bowed pointer to a function which expect a borrowed pointer so we should be able to do the comparison. I didn't found in the documentation a way to convert explicitly a shared pointer to a borrowed pointer. For example, we should be able to do something like this:
let a = @10;
let b: &int = a;
or maybe:
let b: &int = a.convert_to_borrowed;

@nikomatsakis
Copy link
Contributor

The first example ought to work, I think, it's a bug in the type inferencer. Basically it should ensure that if you have an expression a == b then there is a common supertype T such that type(a) <: T and type(b) <: T, but I guess it's not doing that.

@nikomatsakis
Copy link
Contributor

Regarding an explicit conversion to a borrowed pointer, the explicit way to write it for @T to &T is &*a (that is, take the address of the dereference of a). However, I think we will add a method into the standard library, so that you can write "a.borrow()". The compiler will automatically borrow for you in function calls (if the expected type of the parameter is &T and you supply @T).

@ghost ghost assigned nikomatsakis Aug 30, 2012
@bblum
Copy link
Contributor

bblum commented Sep 4, 2012

Perhaps this should be supported inherently. In the meantime, we have ptr::ref_eq for this use case which takes two pointers with a fresh region variable on each one.

@nikomatsakis
Copy link
Contributor

Reading the type check code, I see that there was a special bit of code for doing == comparisons which does not seem to be enforcing the correct requirement (that the two values being compared have a common supertype). I will fix that, it may fix this bug, though due to the limitations of our type inferencer it also may not.

@nielsegberts
Copy link
Contributor

The example compiles, also with "b: @int" in the prototype. I think this bug can be closed?

@nikomatsakis
Copy link
Contributor

Agreed.

bors pushed a commit to rust-lang-ci/rust that referenced this issue May 15, 2021
RalfJung pushed a commit to RalfJung/rust that referenced this issue Feb 17, 2024
Miri has used the `target/miri` subdirectory since 2021 to keep itself
separate from non-miri builds, so this should not be necessary.

See commit 6a18683

Since the items are no longer a sequence of steps to do in
order ("first, make sure that ..."), switch to an unordered list while
we're at it.

Closes rust-lang#3289
RalfJung pushed a commit to RalfJung/rust that referenced this issue Feb 17, 2024
Stop recommending cargo clean in README

Miri has used the `target/miri` subdirectory since 2021 to keep itself separate from non-miri builds, so this should not be necessary.

See commit 6a18683

Since the items are no longer a sequence of steps to do in order ("first, make sure that ..."), switch to an unordered list while we're at it.

Closes rust-lang#3289
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

No branches or pull requests

5 participants