mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
Rollup merge of #117411 - oli-obk:query_merge_immobile_game, r=compiler-errors,Nilstrieb
Improve some diagnostics around `?Trait` bounds * uses better spans * clarifies a message that was only talking about generic params, but applies to `dyn ?Trait` and `impl ?Trait` as well
This commit is contained in:
commit
3e95c6ab03
@ -8,6 +8,7 @@ use rustc_middle::ty::{self as ty, Ty, TypeVisitableExt};
|
|||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::{ErrorGuaranteed, Span};
|
use rustc_span::{ErrorGuaranteed, Span};
|
||||||
use rustc_trait_selection::traits;
|
use rustc_trait_selection::traits;
|
||||||
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use crate::astconv::{
|
use crate::astconv::{
|
||||||
AstConv, ConvertedBinding, ConvertedBindingKind, OnlySelfBounds, PredicateFilter,
|
AstConv, ConvertedBinding, ConvertedBindingKind, OnlySelfBounds, PredicateFilter,
|
||||||
@ -28,15 +29,11 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
// Try to find an unbound in bounds.
|
// Try to find an unbound in bounds.
|
||||||
let mut unbound = None;
|
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
|
||||||
let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| {
|
let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| {
|
||||||
for ab in ast_bounds {
|
for ab in ast_bounds {
|
||||||
if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab {
|
if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab {
|
||||||
if unbound.is_none() {
|
unbounds.push(ptr)
|
||||||
unbound = Some(&ptr.trait_ref);
|
|
||||||
} else {
|
|
||||||
tcx.sess.emit_err(errors::MultipleRelaxedDefaultBounds { span });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -51,33 +48,41 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let sized_def_id = tcx.lang_items().sized_trait();
|
if unbounds.len() > 1 {
|
||||||
match (&sized_def_id, unbound) {
|
tcx.sess.emit_err(errors::MultipleRelaxedDefaultBounds {
|
||||||
(Some(sized_def_id), Some(tpb))
|
spans: unbounds.iter().map(|ptr| ptr.span).collect(),
|
||||||
if tpb.path.res == Res::Def(DefKind::Trait, *sized_def_id) =>
|
});
|
||||||
{
|
|
||||||
// There was in fact a `?Sized` bound, return without doing anything
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
(_, Some(_)) => {
|
|
||||||
// There was a `?Trait` bound, but it was not `?Sized`; warn.
|
|
||||||
tcx.sess.span_warn(
|
|
||||||
span,
|
|
||||||
"default bound relaxed for a type parameter, but \
|
|
||||||
this does nothing because the given bound is not \
|
|
||||||
a default; only `?Sized` is supported",
|
|
||||||
);
|
|
||||||
// Otherwise, add implicitly sized if `Sized` is available.
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// There was no `?Sized` bound; add implicitly sized if `Sized` is available.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let sized_def_id = tcx.lang_items().sized_trait();
|
||||||
|
|
||||||
|
let mut seen_sized_unbound = false;
|
||||||
|
for unbound in unbounds {
|
||||||
|
if let Some(sized_def_id) = sized_def_id {
|
||||||
|
if unbound.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id) {
|
||||||
|
seen_sized_unbound = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// There was a `?Trait` bound, but it was not `?Sized`; warn.
|
||||||
|
tcx.sess.span_warn(
|
||||||
|
unbound.span,
|
||||||
|
"relaxing a default bound only does something for `?Sized`; \
|
||||||
|
all other traits are not bound by default",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the above loop finished there was no `?Sized` bound; add implicitly sized if `Sized` is available.
|
||||||
if sized_def_id.is_none() {
|
if sized_def_id.is_none() {
|
||||||
// No lang item for `Sized`, so we can't add it as a bound.
|
// No lang item for `Sized`, so we can't add it as a bound.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bounds.push_sized(tcx, self_ty, span);
|
if seen_sized_unbound {
|
||||||
|
// There was in fact a `?Sized` bound, return without doing anything
|
||||||
|
} else {
|
||||||
|
// There was no `?Sized` bound; add implicitly sized if `Sized` is available.
|
||||||
|
bounds.push_sized(tcx, self_ty, span);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This helper takes a *converted* parameter type (`param_ty`)
|
/// This helper takes a *converted* parameter type (`param_ty`)
|
||||||
|
@ -96,7 +96,7 @@ pub struct CopyImplOnTypeWithDtor {
|
|||||||
#[diag(hir_analysis_multiple_relaxed_default_bounds, code = "E0203")]
|
#[diag(hir_analysis_multiple_relaxed_default_bounds, code = "E0203")]
|
||||||
pub struct MultipleRelaxedDefaultBounds {
|
pub struct MultipleRelaxedDefaultBounds {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub spans: Vec<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
struct Foo<T: ?Hash> { }
|
struct Foo<T: ?Hash> {}
|
||||||
//~^ ERROR expected trait, found derive macro `Hash`
|
//~^ ERROR expected trait, found derive macro `Hash`
|
||||||
//~^^ ERROR parameter `T` is never used
|
//~^^ ERROR parameter `T` is never used
|
||||||
//~^^^ WARN default bound relaxed for a type parameter, but this does nothing
|
//~^^^ WARN relaxing a default bound only does something for `?Sized`
|
||||||
|
|
||||||
fn main() { }
|
fn main() {}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
error[E0404]: expected trait, found derive macro `Hash`
|
error[E0404]: expected trait, found derive macro `Hash`
|
||||||
--> $DIR/issue-37534.rs:1:16
|
--> $DIR/issue-37534.rs:1:16
|
||||||
|
|
|
|
||||||
LL | struct Foo<T: ?Hash> { }
|
LL | struct Foo<T: ?Hash> {}
|
||||||
| ^^^^ not a trait
|
| ^^^^ not a trait
|
||||||
|
|
|
|
||||||
help: consider importing this trait instead
|
help: consider importing this trait instead
|
||||||
@ -9,16 +9,16 @@ help: consider importing this trait instead
|
|||||||
LL + use std::hash::Hash;
|
LL + use std::hash::Hash;
|
||||||
|
|
|
|
||||||
|
|
||||||
warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
|
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
|
||||||
--> $DIR/issue-37534.rs:1:12
|
--> $DIR/issue-37534.rs:1:15
|
||||||
|
|
|
|
||||||
LL | struct Foo<T: ?Hash> { }
|
LL | struct Foo<T: ?Hash> {}
|
||||||
| ^
|
| ^^^^^
|
||||||
|
|
||||||
error[E0392]: parameter `T` is never used
|
error[E0392]: parameter `T` is never used
|
||||||
--> $DIR/issue-37534.rs:1:12
|
--> $DIR/issue-37534.rs:1:12
|
||||||
|
|
|
|
||||||
LL | struct Foo<T: ?Hash> { }
|
LL | struct Foo<T: ?Hash> {}
|
||||||
| ^ unused parameter
|
| ^ unused parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
// Check that these function definitions only emit warnings, not errors
|
// Check that these function definitions only emit warnings, not errors
|
||||||
fn arg<T: ?Send>(_: T) {}
|
fn arg<T: ?Send>(_: T) {}
|
||||||
//~^ warning: default bound relaxed for a type parameter, but this does nothing
|
//~^ warning: relaxing a default bound only does something for `?Sized`
|
||||||
fn ref_arg<T: ?Send>(_: &T) {}
|
fn ref_arg<T: ?Send>(_: &T) {}
|
||||||
//~^ warning: default bound relaxed for a type parameter, but this does nothing
|
//~^ warning: relaxing a default bound only does something for `?Sized`
|
||||||
fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() }
|
fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() }
|
||||||
//~^ warning: default bound relaxed for a type parameter, but this does nothing
|
//~^ warning: relaxing a default bound only does something for `?Sized`
|
||||||
|
|
||||||
// Check that there's no `?Sized` relaxation!
|
// Check that there's no `?Sized` relaxation!
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
|
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
|
||||||
--> $DIR/issue-87199.rs:8:8
|
--> $DIR/issue-87199.rs:8:11
|
||||||
|
|
|
|
||||||
LL | fn arg<T: ?Send>(_: T) {}
|
LL | fn arg<T: ?Send>(_: T) {}
|
||||||
| ^
|
| ^^^^^
|
||||||
|
|
||||||
warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
|
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
|
||||||
--> $DIR/issue-87199.rs:10:12
|
--> $DIR/issue-87199.rs:10:15
|
||||||
|
|
|
|
||||||
LL | fn ref_arg<T: ?Send>(_: &T) {}
|
LL | fn ref_arg<T: ?Send>(_: &T) {}
|
||||||
| ^
|
| ^^^^^
|
||||||
|
|
||||||
warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
|
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
|
||||||
--> $DIR/issue-87199.rs:12:13
|
--> $DIR/issue-87199.rs:12:40
|
||||||
|
|
|
|
||||||
LL | fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() }
|
LL | fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
||||||
--> $DIR/issue-87199.rs:18:15
|
--> $DIR/issue-87199.rs:18:15
|
||||||
|
@ -11,11 +11,11 @@ trait Trait<'a> {}
|
|||||||
|
|
||||||
struct S4<T>(T) where for<'a> T: ?Trait<'a>;
|
struct S4<T>(T) where for<'a> T: ?Trait<'a>;
|
||||||
//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared
|
//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared
|
||||||
//~| WARN default bound relaxed for a type parameter
|
//~| WARN relaxing a default bound only does something for `?Sized`
|
||||||
|
|
||||||
struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
|
struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
|
||||||
//~^ ERROR type parameter has more than one relaxed default bound
|
//~^ ERROR type parameter has more than one relaxed default bound
|
||||||
//~| WARN default bound relaxed for a type parameter
|
//~| WARN relaxing a default bound only does something for `?Sized`
|
||||||
|
|
||||||
impl<T> S1<T> {
|
impl<T> S1<T> {
|
||||||
fn f() where T: ?Sized {}
|
fn f() where T: ?Sized {}
|
||||||
|
@ -28,23 +28,23 @@ error: `?Trait` bounds are only permitted at the point where a type parameter is
|
|||||||
LL | fn f() where T: ?Sized {}
|
LL | fn f() where T: ?Sized {}
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
|
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
|
||||||
--> $DIR/maybe-bounds-where.rs:12:11
|
--> $DIR/maybe-bounds-where.rs:12:34
|
||||||
|
|
|
|
||||||
LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
|
LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
|
||||||
| ^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
|
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
|
||||||
--> $DIR/maybe-bounds-where.rs:16:11
|
--> $DIR/maybe-bounds-where.rs:16:33
|
||||||
|
|
|
|
||||||
LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
|
LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
|
||||||
| ^
|
| ^^^^^^^^^^^^^^^ ^^^^^^
|
||||||
|
|
||||||
warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
|
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
|
||||||
--> $DIR/maybe-bounds-where.rs:16:11
|
--> $DIR/maybe-bounds-where.rs:16:33
|
||||||
|
|
|
|
||||||
LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
|
LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
|
||||||
| ^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 6 previous errors; 2 warnings emitted
|
error: aborting due to 6 previous errors; 2 warnings emitted
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user