Any method returning a reference will be considered as borrow from self?

any method returning a reference will be considered as borrow from self?

the following code cant be compiled with error both pochis_name and x being borrowed from pochi

#![feature(core_intrinsics)]
struct Brute {
    name: String,
    cry: String,
}

impl Brute {
    fn new() -> Self {
        Self { name: "Pochi".into(), cry: "WOOF!".into() }
    }

    
    fn get_name(&self) -> &i32 { 
        &9
    }

    fn set_cry(&mut self, cry: &str) -> bool {
        self.cry = cry.to_ascii_uppercase();
        true
    }
}

fn main() {
    let mut pochi = Brute::new();
    let pochis_name = pochi.get_name(); 
    let x = &mut pochi;
    let cry =pochis_name.to_string();
}

If you omit lifetimes, they are considered as same. i.e.

    fn get_name(&self) -> &i32 { 
        &9
    }

is same as:

    fn get_name<'a>(&'a self) -> &'a i32 { 
        &9
    }

.
If you want to use another lifetime, specify explicitly.

    fn get_name(&self) -> &'static i32 { 
        &9
    }

By this change, the example compiles.

The reference document has a page describing what happens when lifetimes are omitted.

Lifetime elision - The Rust Reference
https://doc.rust-lang.org/reference/lifetime-elision.html

This is correct.

If we were to explicitly write out the lifetime annotations for get_name() (as determined by the compiler and the lifetime elision rules) we would get something like this:

fn get_name<'a>(&'a self) -> &'a i32 {
    ...
}

(It doesn't matter that &9 is actually 'static. Lifetime elision is done by just looking at the function signature)

Then when the borrow checker runs on main() it sees pochi is borrowed immutably when assigning the pochis_name variable, then gets borrowed again mutably when assigning x. This is no bueno in Rust, hence the lifetime errors.

so what the borrow means the produced reference have a same lifetime with argment?

Yes. When you return a reference, the compiler will try to determine how long it should live for, and in this case it saw you've got a &self argument so the returned reference will probably live as long as &self.

The lifetime elision rules work for 99% of use cases, and the other 1% you might need to give the compiler a helping hand because it wasn't able to figure out which lifetime you intended.

Because you're currently returning &9 (a pointer to a static integer sitting on the executable's .bss section somewhere) you can get away with changing the signature to get_name(&self) -> &'static i32. However the borrow checker is going to start complaining again when your get_name() method returns &self.name. That's because you try to mutate the pochi variable later (let x = &mut pochi), and because that may invalidate the Brute's name property (i.e. pochis_name could point to garbage) the borrow checker won't allow it and you'll be back to where you started.