Rollup merge of #116805 - Nilstrieb:onunimplemented-std-core-alloc-whatever-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
This commit is contained in:
commit
347f7f3bf4
7 changed files with 37 additions and 64 deletions
|
@ -180,8 +180,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
flags.push((sym::cause, Some("MainFunctionType".to_string())));
|
flags.push((sym::cause, Some("MainFunctionType".to_string())));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all types without trimmed paths.
|
// Add all types without trimmed paths or visible paths, ensuring they end up with
|
||||||
ty::print::with_no_trimmed_paths!({
|
// 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 generics = self.tcx.generics_of(def_id);
|
||||||
let self_ty = trait_ref.self_ty();
|
let self_ty = trait_ref.self_ty();
|
||||||
// This is also included through the generics list as `Self`,
|
// This is also included through the generics list as `Self`,
|
||||||
|
@ -296,7 +297,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
{
|
{
|
||||||
flags.push((sym::_Self, Some("&[{integral}]".to_owned())));
|
flags.push((sym::_Self, Some("&[{integral}]".to_owned())));
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
|
||||||
if let Ok(Some(command)) = OnUnimplementedDirective::of_item(self.tcx, def_id) {
|
if let Ok(Some(command)) = OnUnimplementedDirective::of_item(self.tcx, def_id) {
|
||||||
command.evaluate(self.tcx, trait_ref, &flags)
|
command.evaluate(self.tcx, trait_ref, &flags)
|
||||||
|
@ -578,7 +579,9 @@ impl<'tcx> OnUnimplementedDirective {
|
||||||
Some(tcx.features()),
|
Some(tcx.features()),
|
||||||
&mut |cfg| {
|
&mut |cfg| {
|
||||||
let value = cfg.value.map(|v| {
|
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))
|
options.contains(&(cfg.name, value))
|
||||||
|
|
|
@ -573,7 +573,7 @@ pub trait Into<T>: Sized {
|
||||||
#[rustc_diagnostic_item = "From"]
|
#[rustc_diagnostic_item = "From"]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_on_unimplemented(on(
|
#[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",
|
note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix",
|
||||||
))]
|
))]
|
||||||
pub trait From<T>: Sized {
|
pub trait From<T>: Sized {
|
||||||
|
|
|
@ -27,13 +27,13 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_on_unimplemented(
|
#[rustc_on_unimplemented(
|
||||||
on(
|
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",
|
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 \
|
note = "`..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a \
|
||||||
bounded `Range`: `0..end`"
|
bounded `Range`: `0..end`"
|
||||||
),
|
),
|
||||||
on(
|
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",
|
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 \
|
note = "`..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant \
|
||||||
to have a bounded `RangeInclusive`: `0..=end`"
|
to have a bounded `RangeInclusive`: `0..=end`"
|
||||||
|
@ -44,7 +44,7 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
|
||||||
),
|
),
|
||||||
on(_Self = "&[]", label = "`{Self}` is not an iterator; try calling `.iter()`"),
|
on(_Self = "&[]", label = "`{Self}` is not an iterator; try calling `.iter()`"),
|
||||||
on(
|
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()`"
|
label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`"
|
||||||
),
|
),
|
||||||
on(
|
on(
|
||||||
|
@ -52,7 +52,7 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
|
||||||
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
|
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
|
||||||
),
|
),
|
||||||
on(
|
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()`"
|
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
|
||||||
),
|
),
|
||||||
on(
|
on(
|
||||||
|
|
|
@ -573,59 +573,59 @@ impl<T: ?Sized> Copy for &T {}
|
||||||
#[lang = "sync"]
|
#[lang = "sync"]
|
||||||
#[rustc_on_unimplemented(
|
#[rustc_on_unimplemented(
|
||||||
on(
|
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"
|
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::OnceLock` instead"
|
||||||
),
|
),
|
||||||
on(
|
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",
|
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU8` instead",
|
||||||
),
|
),
|
||||||
on(
|
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",
|
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU16` instead",
|
||||||
),
|
),
|
||||||
on(
|
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",
|
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU32` instead",
|
||||||
),
|
),
|
||||||
on(
|
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",
|
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU64` instead",
|
||||||
),
|
),
|
||||||
on(
|
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",
|
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicUsize` instead",
|
||||||
),
|
),
|
||||||
on(
|
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",
|
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI8` instead",
|
||||||
),
|
),
|
||||||
on(
|
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",
|
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI16` instead",
|
||||||
),
|
),
|
||||||
on(
|
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",
|
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead",
|
||||||
),
|
),
|
||||||
on(
|
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",
|
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI64` instead",
|
||||||
),
|
),
|
||||||
on(
|
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",
|
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicIsize` instead",
|
||||||
),
|
),
|
||||||
on(
|
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",
|
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicBool` instead",
|
||||||
),
|
),
|
||||||
on(
|
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`",
|
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock`",
|
||||||
),
|
),
|
||||||
on(
|
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",
|
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",
|
message = "`{Self}` cannot be shared between threads safely",
|
||||||
|
|
|
@ -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>"
|
see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
|
||||||
),
|
),
|
||||||
on(
|
on(
|
||||||
any(_Self = "alloc::string::String", _Self = "std::string::String"),
|
_Self = "alloc::string::String",
|
||||||
note = "you can use `.chars().nth()` or `.bytes().nth()`
|
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>"
|
see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
|
||||||
),
|
),
|
||||||
|
|
|
@ -226,14 +226,8 @@ pub trait Try: FromResidual {
|
||||||
on(
|
on(
|
||||||
all(
|
all(
|
||||||
from_desugaring = "QuestionMark",
|
from_desugaring = "QuestionMark",
|
||||||
any(
|
_Self = "core::result::Result<T, E>",
|
||||||
_Self = "core::result::Result<T, E>",
|
R = "core::option::Option<core::convert::Infallible>",
|
||||||
_Self = "std::result::Result<T, E>",
|
|
||||||
),
|
|
||||||
any(
|
|
||||||
R = "core::option::Option<core::convert::Infallible>",
|
|
||||||
R = "std::option::Option<std::convert::Infallible>",
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
message = "the `?` operator can only be used on `Result`s, not `Option`s, \
|
message = "the `?` operator can only be used on `Result`s, not `Option`s, \
|
||||||
in {ItemContext} that returns `Result`",
|
in {ItemContext} that returns `Result`",
|
||||||
|
@ -243,10 +237,7 @@ pub trait Try: FromResidual {
|
||||||
on(
|
on(
|
||||||
all(
|
all(
|
||||||
from_desugaring = "QuestionMark",
|
from_desugaring = "QuestionMark",
|
||||||
any(
|
_Self = "core::result::Result<T, E>",
|
||||||
_Self = "core::result::Result<T, E>",
|
|
||||||
_Self = "std::result::Result<T, E>",
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
// There's a special error message in the trait selection code for
|
// There's a special error message in the trait selection code for
|
||||||
// `From` in `?`, so this is not shown for result-in-result errors,
|
// `From` in `?`, so this is not shown for result-in-result errors,
|
||||||
|
@ -259,14 +250,8 @@ pub trait Try: FromResidual {
|
||||||
on(
|
on(
|
||||||
all(
|
all(
|
||||||
from_desugaring = "QuestionMark",
|
from_desugaring = "QuestionMark",
|
||||||
any(
|
_Self = "core::option::Option<T>",
|
||||||
_Self = "core::option::Option<T>",
|
R = "core::result::Result<T, E>",
|
||||||
_Self = "std::option::Option<T>",
|
|
||||||
),
|
|
||||||
any(
|
|
||||||
R = "core::result::Result<T, E>",
|
|
||||||
R = "std::result::Result<T, E>",
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
message = "the `?` operator can only be used on `Option`s, not `Result`s, \
|
message = "the `?` operator can only be used on `Option`s, not `Result`s, \
|
||||||
in {ItemContext} that returns `Option`",
|
in {ItemContext} that returns `Option`",
|
||||||
|
@ -276,10 +261,7 @@ pub trait Try: FromResidual {
|
||||||
on(
|
on(
|
||||||
all(
|
all(
|
||||||
from_desugaring = "QuestionMark",
|
from_desugaring = "QuestionMark",
|
||||||
any(
|
_Self = "core::option::Option<T>",
|
||||||
_Self = "core::option::Option<T>",
|
|
||||||
_Self = "std::option::Option<T>",
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
// `Option`-in-`Option` always works, as there's only one possible
|
// `Option`-in-`Option` always works, as there's only one possible
|
||||||
// residual, so this can also be phrased strongly.
|
// residual, so this can also be phrased strongly.
|
||||||
|
@ -291,14 +273,8 @@ pub trait Try: FromResidual {
|
||||||
on(
|
on(
|
||||||
all(
|
all(
|
||||||
from_desugaring = "QuestionMark",
|
from_desugaring = "QuestionMark",
|
||||||
any(
|
_Self = "core::ops::control_flow::ControlFlow<B, C>",
|
||||||
_Self = "core::ops::ControlFlow<B, C>",
|
R = "core::ops::control_flow::ControlFlow<B, C>",
|
||||||
_Self = "std::ops::ControlFlow<B, C>",
|
|
||||||
),
|
|
||||||
any(
|
|
||||||
R = "core::ops::ControlFlow<B, C>",
|
|
||||||
R = "std::ops::ControlFlow<B, C>",
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
message = "the `?` operator in {ItemContext} that returns `ControlFlow<B, _>` \
|
message = "the `?` operator in {ItemContext} that returns `ControlFlow<B, _>` \
|
||||||
can only be used on other `ControlFlow<B, _>`s (with the same Break type)",
|
can only be used on other `ControlFlow<B, _>`s (with the same Break type)",
|
||||||
|
@ -309,10 +285,7 @@ pub trait Try: FromResidual {
|
||||||
on(
|
on(
|
||||||
all(
|
all(
|
||||||
from_desugaring = "QuestionMark",
|
from_desugaring = "QuestionMark",
|
||||||
any(
|
_Self = "core::ops::control_flow::ControlFlow<B, C>",
|
||||||
_Self = "core::ops::ControlFlow<B, C>",
|
|
||||||
_Self = "std::ops::ControlFlow<B, C>",
|
|
||||||
)
|
|
||||||
// `R` is not a `ControlFlow`, as that case was matched previously
|
// `R` is not a `ControlFlow`, as that case was matched previously
|
||||||
),
|
),
|
||||||
message = "the `?` operator can only be used on `ControlFlow`s \
|
message = "the `?` operator can only be used on `ControlFlow`s \
|
||||||
|
|
|
@ -152,10 +152,7 @@ mod private_slice_index {
|
||||||
#[rustc_on_unimplemented(
|
#[rustc_on_unimplemented(
|
||||||
on(T = "str", label = "string indices are ranges of `usize`",),
|
on(T = "str", label = "string indices are ranges of `usize`",),
|
||||||
on(
|
on(
|
||||||
all(
|
all(any(T = "str", T = "&str", T = "alloc::string::String"), _Self = "{integer}"),
|
||||||
any(T = "str", T = "&str", T = "alloc::string::String", T = "std::string::String"),
|
|
||||||
_Self = "{integer}"
|
|
||||||
),
|
|
||||||
note = "you can use `.chars().nth()` or `.bytes().nth()`\n\
|
note = "you can use `.chars().nth()` or `.bytes().nth()`\n\
|
||||||
for more information, see chapter 8 in The Book: \
|
for more information, see chapter 8 in The Book: \
|
||||||
<https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
|
<https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue