Skip to content

Commit

Permalink
Rollup merge of #116805 - Nilstrieb:onunimplemented-std-core-alloc-wh…
Browse files Browse the repository at this point in the history
…atever-who-cares, r=compiler-errors

Make `rustc_onunimplemented` export path agnostic

This makes it so that all the matchers that match against paths use the definition path instead of the export path. This removes all duplication around `std`/`alloc`/`core`.

This is not necessarily optimal because we now depend on internal implementation details like `core::ops::control_flow::ControlFlow`, which is not very nice and probably not acceptable for a stable `on_unimplemented`.

An alternative would be to just string-replace normalize away `alloc`/`core` to `std` as a special case, keeping the export paths but making it so that we're still fully standard library flavor agnostic.

Looking at the diff, I'm starting to think that some simple string replacement would go a long way towards fixing the problem of duplication while keeping export paths...

What do you prefer?

Also `@weiznich` for your thoughts about the stable version.

r? compiler-errors
  • Loading branch information
GuillaumeGomez authored Oct 16, 2023
2 parents d0ade3f + 414135d commit 347f7f3
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
flags.push((sym::cause, Some("MainFunctionType".to_string())));
}

// Add all types without trimmed paths.
ty::print::with_no_trimmed_paths!({
// Add all types without trimmed paths or visible paths, ensuring they end up with
// their "canonical" def path.
ty::print::with_no_trimmed_paths!(ty::print::with_no_visible_paths!({
let generics = self.tcx.generics_of(def_id);
let self_ty = trait_ref.self_ty();
// This is also included through the generics list as `Self`,
Expand Down Expand Up @@ -296,7 +297,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
{
flags.push((sym::_Self, Some("&[{integral}]".to_owned())));
}
});
}));

if let Ok(Some(command)) = OnUnimplementedDirective::of_item(self.tcx, def_id) {
command.evaluate(self.tcx, trait_ref, &flags)
Expand Down Expand Up @@ -578,7 +579,9 @@ impl<'tcx> OnUnimplementedDirective {
Some(tcx.features()),
&mut |cfg| {
let value = cfg.value.map(|v| {
OnUnimplementedFormatString(v).format(tcx, trait_ref, &options_map)
// `with_no_visible_paths` is also used when generating the options,
// so we need to match it here.
ty::print::with_no_visible_paths!(OnUnimplementedFormatString(v).format(tcx, trait_ref, &options_map))
});

options.contains(&(cfg.name, value))
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/convert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ pub trait Into<T>: Sized {
#[rustc_diagnostic_item = "From"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented(on(
all(_Self = "&str", any(T = "alloc::string::String", T = "std::string::String")),
all(_Self = "&str", T = "alloc::string::String"),
note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix",
))]
pub trait From<T>: Sized {
Expand Down
8 changes: 4 additions & 4 deletions library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented(
on(
any(_Self = "core::ops::RangeTo<Idx>", _Self = "std::ops::RangeTo<Idx>"),
_Self = "core::ops::range::RangeTo<Idx>",
label = "if you meant to iterate until a value, add a starting value",
note = "`..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a \
bounded `Range`: `0..end`"
),
on(
any(_Self = "core::ops::RangeToInclusive<Idx>", _Self = "std::ops::RangeToInclusive<Idx>"),
_Self = "core::ops::range::RangeToInclusive<Idx>",
label = "if you meant to iterate until a value (including it), add a starting value",
note = "`..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant \
to have a bounded `RangeInclusive`: `0..=end`"
Expand All @@ -44,15 +44,15 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
),
on(_Self = "&[]", label = "`{Self}` is not an iterator; try calling `.iter()`"),
on(
any(_Self = "alloc::vec::Vec<T, A>", _Self = "std::vec::Vec<T, A>"),
_Self = "alloc::vec::Vec<T, A>",
label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`"
),
on(
_Self = "&str",
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
),
on(
any(_Self = "alloc::string::String", _Self = "std::string::String"),
_Self = "alloc::string::String",
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
),
on(
Expand Down
28 changes: 14 additions & 14 deletions library/core/src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -573,59 +573,59 @@ impl<T: ?Sized> Copy for &T {}
#[lang = "sync"]
#[rustc_on_unimplemented(
on(
any(_Self = "core::cell:OnceCell<T>", _Self = "std::cell::OnceCell<T>"),
_Self = "core::cell::once::OnceCell<T>",
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::OnceLock` instead"
),
on(
any(_Self = "core::cell::Cell<u8>", _Self = "std::cell::Cell<u8>"),
_Self = "core::cell::Cell<u8>",
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU8` instead",
),
on(
any(_Self = "core::cell::Cell<u16>", _Self = "std::cell::Cell<u16>"),
_Self = "core::cell::Cell<u16>",
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU16` instead",
),
on(
any(_Self = "core::cell::Cell<u32>", _Self = "std::cell::Cell<u32>"),
_Self = "core::cell::Cell<u32>",
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU32` instead",
),
on(
any(_Self = "core::cell::Cell<u64>", _Self = "std::cell::Cell<u64>"),
_Self = "core::cell::Cell<u64>",
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU64` instead",
),
on(
any(_Self = "core::cell::Cell<usize>", _Self = "std::cell::Cell<usize>"),
_Self = "core::cell::Cell<usize>",
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicUsize` instead",
),
on(
any(_Self = "core::cell::Cell<i8>", _Self = "std::cell::Cell<i8>"),
_Self = "core::cell::Cell<i8>",
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI8` instead",
),
on(
any(_Self = "core::cell::Cell<i16>", _Self = "std::cell::Cell<i16>"),
_Self = "core::cell::Cell<i16>",
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI16` instead",
),
on(
any(_Self = "core::cell::Cell<i32>", _Self = "std::cell::Cell<i32>"),
_Self = "core::cell::Cell<i32>",
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead",
),
on(
any(_Self = "core::cell::Cell<i64>", _Self = "std::cell::Cell<i64>"),
_Self = "core::cell::Cell<i64>",
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI64` instead",
),
on(
any(_Self = "core::cell::Cell<isize>", _Self = "std::cell::Cell<isize>"),
_Self = "core::cell::Cell<isize>",
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicIsize` instead",
),
on(
any(_Self = "core::cell::Cell<bool>", _Self = "std::cell::Cell<bool>"),
_Self = "core::cell::Cell<bool>",
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicBool` instead",
),
on(
any(_Self = "core::cell::Cell<T>", _Self = "std::cell::Cell<T>"),
_Self = "core::cell::Cell<T>",
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock`",
),
on(
any(_Self = "core::cell::RefCell<T>", _Self = "std::cell::RefCell<T>"),
_Self = "core::cell::RefCell<T>",
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead",
),
message = "`{Self}` cannot be shared between threads safely",
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/ops/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#ind
see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
),
on(
any(_Self = "alloc::string::String", _Self = "std::string::String"),
_Self = "alloc::string::String",
note = "you can use `.chars().nth()` or `.bytes().nth()`
see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
),
Expand Down
45 changes: 9 additions & 36 deletions library/core/src/ops/try_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,14 +226,8 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
any(
_Self = "core::result::Result<T, E>",
_Self = "std::result::Result<T, E>",
),
any(
R = "core::option::Option<core::convert::Infallible>",
R = "std::option::Option<std::convert::Infallible>",
)
_Self = "core::result::Result<T, E>",
R = "core::option::Option<core::convert::Infallible>",
),
message = "the `?` operator can only be used on `Result`s, not `Option`s, \
in {ItemContext} that returns `Result`",
Expand All @@ -243,10 +237,7 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
any(
_Self = "core::result::Result<T, E>",
_Self = "std::result::Result<T, E>",
)
_Self = "core::result::Result<T, E>",
),
// There's a special error message in the trait selection code for
// `From` in `?`, so this is not shown for result-in-result errors,
Expand All @@ -259,14 +250,8 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
any(
_Self = "core::option::Option<T>",
_Self = "std::option::Option<T>",
),
any(
R = "core::result::Result<T, E>",
R = "std::result::Result<T, E>",
)
_Self = "core::option::Option<T>",
R = "core::result::Result<T, E>",
),
message = "the `?` operator can only be used on `Option`s, not `Result`s, \
in {ItemContext} that returns `Option`",
Expand All @@ -276,10 +261,7 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
any(
_Self = "core::option::Option<T>",
_Self = "std::option::Option<T>",
)
_Self = "core::option::Option<T>",
),
// `Option`-in-`Option` always works, as there's only one possible
// residual, so this can also be phrased strongly.
Expand All @@ -291,14 +273,8 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
any(
_Self = "core::ops::ControlFlow<B, C>",
_Self = "std::ops::ControlFlow<B, C>",
),
any(
R = "core::ops::ControlFlow<B, C>",
R = "std::ops::ControlFlow<B, C>",
)
_Self = "core::ops::control_flow::ControlFlow<B, C>",
R = "core::ops::control_flow::ControlFlow<B, C>",
),
message = "the `?` operator in {ItemContext} that returns `ControlFlow<B, _>` \
can only be used on other `ControlFlow<B, _>`s (with the same Break type)",
Expand All @@ -309,10 +285,7 @@ pub trait Try: FromResidual {
on(
all(
from_desugaring = "QuestionMark",
any(
_Self = "core::ops::ControlFlow<B, C>",
_Self = "std::ops::ControlFlow<B, C>",
)
_Self = "core::ops::control_flow::ControlFlow<B, C>",
// `R` is not a `ControlFlow`, as that case was matched previously
),
message = "the `?` operator can only be used on `ControlFlow`s \
Expand Down
5 changes: 1 addition & 4 deletions library/core/src/slice/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,7 @@ mod private_slice_index {
#[rustc_on_unimplemented(
on(T = "str", label = "string indices are ranges of `usize`",),
on(
all(
any(T = "str", T = "&str", T = "alloc::string::String", T = "std::string::String"),
_Self = "{integer}"
),
all(any(T = "str", T = "&str", T = "alloc::string::String"), _Self = "{integer}"),
note = "you can use `.chars().nth()` or `.bytes().nth()`\n\
for more information, see chapter 8 in The Book: \
<https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
Expand Down

0 comments on commit 347f7f3

Please sign in to comment.