mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-04 19:12:50 +00:00
Fix checking of auto trait bounds in trait objects.
Any auto trait is allowed in trait object bounds. Fix duplicate check of type and lifetime parameter count.
This commit is contained in:
parent
d762b1d6c6
commit
f46f388cb2
@ -572,8 +572,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||||||
let b = &trait_bounds[0];
|
let b = &trait_bounds[0];
|
||||||
let span = b.trait_ref.path.span;
|
let span = b.trait_ref.path.span;
|
||||||
struct_span_err!(self.tcx().sess, span, E0225,
|
struct_span_err!(self.tcx().sess, span, E0225,
|
||||||
"only Send/Sync traits can be used as additional traits in a trait object")
|
"only auto traits can be used as additional traits in a trait object")
|
||||||
.span_label(span, "non-Send/Sync additional trait")
|
.span_label(span, "non-auto additional trait")
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1311,27 +1311,10 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
|||||||
-> (Vec<DefId>, Vec<&'b hir::PolyTraitRef>)
|
-> (Vec<DefId>, Vec<&'b hir::PolyTraitRef>)
|
||||||
{
|
{
|
||||||
let (auto_traits, trait_bounds): (Vec<_>, _) = trait_bounds.iter().partition(|bound| {
|
let (auto_traits, trait_bounds): (Vec<_>, _) = trait_bounds.iter().partition(|bound| {
|
||||||
|
// Checks whether `trait_did` is an auto trait and adds it to `auto_traits` if so.
|
||||||
match bound.trait_ref.path.def {
|
match bound.trait_ref.path.def {
|
||||||
Def::Trait(trait_did) => {
|
Def::Trait(trait_did) if tcx.trait_is_auto(trait_did) => {
|
||||||
// Checks whether `trait_did` refers to one of the builtin
|
true
|
||||||
// traits, like `Send`, and adds it to `auto_traits` if so.
|
|
||||||
if Some(trait_did) == tcx.lang_items().send_trait() ||
|
|
||||||
Some(trait_did) == tcx.lang_items().sync_trait() {
|
|
||||||
let segments = &bound.trait_ref.path.segments;
|
|
||||||
segments[segments.len() - 1].with_parameters(|parameters| {
|
|
||||||
if !parameters.types.is_empty() {
|
|
||||||
check_type_argument_count(tcx, bound.trait_ref.path.span,
|
|
||||||
parameters.types.len(), &[]);
|
|
||||||
}
|
|
||||||
if !parameters.lifetimes.is_empty() {
|
|
||||||
report_lifetime_number_error(tcx, bound.trait_ref.path.span,
|
|
||||||
parameters.lifetimes.len(), 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
|
@ -2455,9 +2455,9 @@ fn main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Send and Sync are an exception to this rule: it's possible to have bounds of
|
Auto traits such as Send and Sync are an exception to this rule:
|
||||||
one non-builtin trait, plus either or both of Send and Sync. For example, the
|
It's possible to have bounds of one non-builtin trait, plus any number of
|
||||||
following compiles correctly:
|
auto traits. For example, the following compiles correctly:
|
||||||
|
|
||||||
```
|
```
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -10,6 +10,6 @@
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _: Box<std::io::Read + std::io::Write>;
|
let _: Box<std::io::Read + std::io::Write>;
|
||||||
//~^ ERROR only Send/Sync traits can be used as additional traits in a trait object [E0225]
|
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||||
//~| NOTE non-Send/Sync additional trait
|
//~| NOTE non-auto additional trait
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ trait Trait {}
|
|||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let x: Vec<Trait + Sized> = Vec::new();
|
let x: Vec<Trait + Sized> = Vec::new();
|
||||||
//~^ ERROR only Send/Sync traits can be used as additional traits in a trait object
|
//~^ ERROR only auto traits can be used as additional traits in a trait object
|
||||||
//~| ERROR the trait bound `Trait: std::marker::Sized` is not satisfied
|
//~| ERROR the trait bound `Trait: std::marker::Sized` is not satisfied
|
||||||
//~| ERROR the trait bound `Trait: std::marker::Sized` is not satisfied
|
//~| ERROR the trait bound `Trait: std::marker::Sized` is not satisfied
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,6 @@ type Test = Add +
|
|||||||
//~| NOTE missing reference to `RHS`
|
//~| NOTE missing reference to `RHS`
|
||||||
//~| NOTE because of the default `Self` reference, type parameters must be specified on object types
|
//~| NOTE because of the default `Self` reference, type parameters must be specified on object types
|
||||||
//~| ERROR E0225
|
//~| ERROR E0225
|
||||||
//~| NOTE non-Send/Sync additional trait
|
//~| NOTE non-auto additional trait
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
@ -16,6 +16,6 @@ fn size_of_copy<T: Copy+?Sized>() -> usize { mem::size_of::<T>() }
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
size_of_copy::<Misc+Copy>();
|
size_of_copy::<Misc+Copy>();
|
||||||
//~^ ERROR only Send/Sync traits can be used as additional traits in a trait object
|
//~^ ERROR only auto traits can be used as additional traits in a trait object
|
||||||
//~| ERROR the trait bound `Misc: std::marker::Copy` is not satisfied
|
//~| ERROR the trait bound `Misc: std::marker::Copy` is not satisfied
|
||||||
}
|
}
|
||||||
|
@ -33,4 +33,7 @@ fn main() {
|
|||||||
take_auto(AutoBool(true));
|
take_auto(AutoBool(true));
|
||||||
take_auto_unsafe(0);
|
take_auto_unsafe(0);
|
||||||
take_auto_unsafe(AutoBool(true));
|
take_auto_unsafe(AutoBool(true));
|
||||||
|
|
||||||
|
/// Auto traits are allowed in trait object bounds.
|
||||||
|
let _: &(Send + Auto) = &0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user