Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3530,6 +3530,24 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
Applicability::MaybeIncorrect,
);
}

if let Some(cow_did) = tcx.get_diagnostic_item(sym::Cow)
&& let ty::Adt(adt_def, _) = return_ty.kind()
&& adt_def.did() == cow_did
{
if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(return_span) {
if let Some(pos) = snippet.rfind(".to_owned") {
Copy link
Copy Markdown
Member

@davidtwco davidtwco Apr 10, 2026

Choose a reason for hiding this comment

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

View changes since the review

It would be nice if we did this in a slightly more structured way - looking for a diagnostic item for the method or something, but for a simple diagnostic like this I'm okay with it

let byte_pos = BytePos(pos as u32 + 1u32);
let to_owned_span = return_span.with_hi(return_span.lo() + byte_pos);
err.span_suggestion_short(
to_owned_span.shrink_to_hi(),
"try using `.into_owned()` if you meant to convert a `Cow<'_, T>` to an owned `T`",
"in",
Applicability::MaybeIncorrect,
);
}
}
}
}

Err(err)
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ symbols! {
Continue,
ControlFlow,
Copy,
Cow,
Debug,
Default,
Deref,
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/clippy_utils/src/sym.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ generate! {
Cargo_toml: "Cargo.toml",
Child,
Command,
Cow,
Current,
DOUBLE_QUOTE: "\"",
DebugStruct,
Expand Down
23 changes: 23 additions & 0 deletions tests/ui/suggestions/cow-into-owned-suggestion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//! Regression test for: https://github.com/rust-lang/rust/issues/144792

fn main() {
let _ = || {
let os_string = std::ffi::OsString::from("test");
os_string.to_string_lossy().to_owned()
//~^ ERROR: cannot return value referencing local variable `os_string` [E0515]
};

let _ = || {
let s = "hello".to_owned();
let cow = std::borrow::Cow::from(&s);
cow.to_owned()
//~^ ERROR: cannot return value referencing local variable `s` [E0515]
};

let _ = || {
let bytes = b"hello".to_owned();
let cow = std::borrow::Cow::from(&bytes[..]);
cow.to_owned()
//~^ ERROR: cannot return value referencing local variable `bytes` [E0515]
};
}
43 changes: 43 additions & 0 deletions tests/ui/suggestions/cow-into-owned-suggestion.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
error[E0515]: cannot return value referencing local variable `os_string`
--> $DIR/cow-into-owned-suggestion.rs:6:9
|
LL | os_string.to_string_lossy().to_owned()
| ---------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| returns a value referencing data owned by the current function
| `os_string` is borrowed here
|
help: try using `.into_owned()` if you meant to convert a `Cow<'_, T>` to an owned `T`
|
LL | os_string.to_string_lossy().into_owned()
| ++

error[E0515]: cannot return value referencing local variable `s`
--> $DIR/cow-into-owned-suggestion.rs:13:9
|
LL | let cow = std::borrow::Cow::from(&s);
| -- `s` is borrowed here
LL | cow.to_owned()
| ^^^^^^^^^^^^^^ returns a value referencing data owned by the current function
|
help: try using `.into_owned()` if you meant to convert a `Cow<'_, T>` to an owned `T`
|
LL | cow.into_owned()
| ++

error[E0515]: cannot return value referencing local variable `bytes`
--> $DIR/cow-into-owned-suggestion.rs:20:9
|
LL | let cow = std::borrow::Cow::from(&bytes[..]);
| ----- `bytes` is borrowed here
LL | cow.to_owned()
| ^^^^^^^^^^^^^^ returns a value referencing data owned by the current function
|
help: try using `.into_owned()` if you meant to convert a `Cow<'_, T>` to an owned `T`
|
LL | cow.into_owned()
| ++

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0515`.
Loading