Auto merge of #104325 - GuillaumeGomez:rollup-19bzwoa, r=GuillaumeGomez

Rollup of 8 pull requests

Successful merges:

 - #104110 (prevent uninitialized access in black_box for zero-sized-types)
 - #104117 (Mark `trait_upcasting` feature no longer incomplete.)
 - #104144 (Suggest removing unnecessary `.` to use a floating point literal)
 - #104250 (Migrate no result page link color to CSS variables)
 - #104261 (More accurately report error when formal and expected signature types differ)
 - #104263 (Add a reference to ilog2 in leading_zeros integer docs)
 - #104308 (Remove the old `ValidAlign` name)
 - #104319 (Fix non clickable source link)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-11-12 17:39:11 +00:00
commit cd128880b1
44 changed files with 377 additions and 133 deletions

View file

@ -340,17 +340,26 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
sym::black_box => {
args[0].val.store(self, result);
let result_val_span = [result.llval];
// We need to "use" the argument in some way LLVM can't introspect, and on
// targets that support it we can typically leverage inline assembly to do
// this. LLVM's interpretation of inline assembly is that it's, well, a black
// box. This isn't the greatest implementation since it probably deoptimizes
// more than we want, but it's so far good enough.
//
// For zero-sized types, the location pointed to by the result may be
// uninitialized. Do not "use" the result in this case; instead just clobber
// the memory.
let (constraint, inputs): (&str, &[_]) = if result.layout.is_zst() {
("~{memory}", &[])
} else {
("r,~{memory}", &result_val_span)
};
crate::asm::inline_asm_call(
self,
"",
"r,~{memory}",
&[result.llval],
constraint,
inputs,
self.type_void(),
true,
false,

View file

@ -512,9 +512,9 @@ declare_features! (
(active, thread_local, "1.0.0", Some(29594), None),
/// Allows defining `trait X = A + B;` alias items.
(active, trait_alias, "1.24.0", Some(41517), None),
/// Allows upcasting trait objects via supertraits.
/// Trait upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
(incomplete, trait_upcasting, "1.56.0", Some(65991), None),
/// Allows dyn upcasting trait objects via supertraits.
/// Dyn upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
(active, trait_upcasting, "1.56.0", Some(65991), None),
/// Allows #[repr(transparent)] on unions (RFC 2645).
(active, transparent_unions, "1.37.0", Some(60405), None),
/// Allows inconsistent bounds in where clauses.

View file

@ -30,6 +30,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
error: Option<TypeError<'tcx>>,
) {
if expr_ty == expected {
return;
}
self.annotate_expected_due_to_let_ty(err, expr, error);
// Use `||` to give these suggestions a precedence
@ -43,7 +47,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|| self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected)
|| self.suggest_copied_or_cloned(err, expr, expr_ty, expected)
|| self.suggest_into(err, expr, expr_ty, expected)
|| self.suggest_option_to_bool(err, expr, expr_ty, expected);
|| self.suggest_option_to_bool(err, expr, expr_ty, expected)
|| self.suggest_floating_point_literal(err, expr, expected);
self.note_type_is_not_clone(err, expected, expr_ty, expr);
self.note_need_for_fn_pointer(err, expected, expr_ty);

View file

@ -597,6 +597,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
};
let mk_trace = |span, (formal_ty, expected_ty), provided_ty| {
let mismatched_ty = if expected_ty == provided_ty {
// If expected == provided, then we must have failed to sup
// the formal type. Avoid printing out "expected Ty, found Ty"
// in that case.
formal_ty
} else {
expected_ty
};
TypeTrace::types(&self.misc(span), true, mismatched_ty, provided_ty)
};
// The algorithm here is inspired by levenshtein distance and longest common subsequence.
// We'll try to detect 4 different types of mistakes:
// - An extra parameter has been provided that doesn't satisfy *any* of the other inputs
@ -661,10 +673,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// A tuple wrap suggestion actually occurs within,
// so don't do anything special here.
err = self.err_ctxt().report_and_explain_type_error(
TypeTrace::types(
&self.misc(*lo),
true,
formal_and_expected_inputs[mismatch_idx.into()].1,
mk_trace(
*lo,
formal_and_expected_inputs[mismatch_idx.into()],
provided_arg_tys[mismatch_idx.into()].0,
),
terr,
@ -748,9 +759,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
errors.drain_filter(|error| {
let Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(Some(e))) = error else { return false };
let (provided_ty, provided_span) = provided_arg_tys[*provided_idx];
let (expected_ty, _) = formal_and_expected_inputs[*expected_idx];
let cause = &self.misc(provided_span);
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
let trace = mk_trace(provided_span, formal_and_expected_inputs[*expected_idx], provided_ty);
if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308(_)) {
self.err_ctxt().report_and_explain_type_error(trace, *e).emit();
return true;
@ -774,8 +783,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
{
let (formal_ty, expected_ty) = formal_and_expected_inputs[*expected_idx];
let (provided_ty, provided_arg_span) = provided_arg_tys[*provided_idx];
let cause = &self.misc(provided_arg_span);
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
let trace = mk_trace(provided_arg_span, (formal_ty, expected_ty), provided_ty);
let mut err = self.err_ctxt().report_and_explain_type_error(trace, *err);
self.emit_coerce_suggestions(
&mut err,
@ -847,8 +855,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let (formal_ty, expected_ty) = formal_and_expected_inputs[expected_idx];
let (provided_ty, provided_span) = provided_arg_tys[provided_idx];
if let Compatibility::Incompatible(error) = compatibility {
let cause = &self.misc(provided_span);
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
let trace = mk_trace(provided_span, (formal_ty, expected_ty), provided_ty);
if let Some(e) = error {
self.err_ctxt().note_type_err(
&mut err,

View file

@ -374,7 +374,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let annotation_span = ty.span;
err.span_suggestion(
annotation_span.with_hi(annotation_span.lo()),
format!("alternatively, consider changing the type annotation"),
"alternatively, consider changing the type annotation",
suggest_annotation,
Applicability::MaybeIncorrect,
);
@ -1204,6 +1204,48 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
#[instrument(skip(self, err))]
pub(crate) fn suggest_floating_point_literal(
&self,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
expected_ty: Ty<'tcx>,
) -> bool {
if !expected_ty.is_floating_point() {
return false;
}
match expr.kind {
ExprKind::Struct(QPath::LangItem(LangItem::Range, ..), [start, end], _) => {
err.span_suggestion_verbose(
start.span.shrink_to_hi().with_hi(end.span.lo()),
"remove the unnecessary `.` operator for a floating point literal",
'.',
Applicability::MaybeIncorrect,
);
true
}
ExprKind::Struct(QPath::LangItem(LangItem::RangeFrom, ..), [start], _) => {
err.span_suggestion_verbose(
expr.span.with_lo(start.span.hi()),
"remove the unnecessary `.` operator for a floating point literal",
'.',
Applicability::MaybeIncorrect,
);
true
}
ExprKind::Struct(QPath::LangItem(LangItem::RangeTo, ..), [end], _) => {
err.span_suggestion_verbose(
expr.span.until(end.span),
"remove the unnecessary `.` operator and add an integer part for a floating point literal",
"0.",
Applicability::MaybeIncorrect,
);
true
}
_ => false,
}
}
fn is_loop(&self, id: hir::HirId) -> bool {
let node = self.tcx.hir().get(id);
matches!(node, Node::Expr(Expr { kind: ExprKind::Loop(..), .. }))

View file

@ -7,8 +7,8 @@
use crate::cmp;
use crate::error::Error;
use crate::fmt;
use crate::mem::{self, ValidAlign};
use crate::ptr::NonNull;
use crate::mem;
use crate::ptr::{Alignment, NonNull};
// While this function is used in one place and its implementation
// could be inlined, the previous attempts to do so made rustc
@ -46,7 +46,7 @@ pub struct Layout {
//
// (However, we do not analogously require `align >= sizeof(void*)`,
// even though that is *also* a requirement of `posix_memalign`.)
align: ValidAlign,
align: Alignment,
}
impl Layout {
@ -71,11 +71,11 @@ impl Layout {
}
// SAFETY: just checked that align is a power of two.
Layout::from_size_valid_align(size, unsafe { ValidAlign::new_unchecked(align) })
Layout::from_size_alignment(size, unsafe { Alignment::new_unchecked(align) })
}
#[inline(always)]
const fn max_size_for_align(align: ValidAlign) -> usize {
const fn max_size_for_align(align: Alignment) -> usize {
// (power-of-two implies align != 0.)
// Rounded up size is:
@ -95,7 +95,7 @@ impl Layout {
/// Internal helper constructor to skip revalidating alignment validity.
#[inline]
const fn from_size_valid_align(size: usize, align: ValidAlign) -> Result<Self, LayoutError> {
const fn from_size_alignment(size: usize, align: Alignment) -> Result<Self, LayoutError> {
if size > Self::max_size_for_align(align) {
return Err(LayoutError);
}
@ -117,7 +117,7 @@ impl Layout {
#[rustc_allow_const_fn_unstable(ptr_alignment_type)]
pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
// SAFETY: the caller is required to uphold the preconditions.
unsafe { Layout { size, align: ValidAlign::new_unchecked(align) } }
unsafe { Layout { size, align: Alignment::new_unchecked(align) } }
}
/// The minimum size in bytes for a memory block of this layout.
@ -321,7 +321,7 @@ impl Layout {
let alloc_size = padded_size.checked_mul(n).ok_or(LayoutError)?;
// The safe constructor is called here to enforce the isize size limit.
Layout::from_size_valid_align(alloc_size, self.align).map(|layout| (layout, padded_size))
Layout::from_size_alignment(alloc_size, self.align).map(|layout| (layout, padded_size))
}
/// Creates a layout describing the record for `self` followed by
@ -379,7 +379,7 @@ impl Layout {
let new_size = offset.checked_add(next.size()).ok_or(LayoutError)?;
// The safe constructor is called here to enforce the isize size limit.
let layout = Layout::from_size_valid_align(new_size, new_align)?;
let layout = Layout::from_size_alignment(new_size, new_align)?;
Ok((layout, offset))
}
@ -400,7 +400,7 @@ impl Layout {
pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> {
let size = self.size().checked_mul(n).ok_or(LayoutError)?;
// The safe constructor is called here to enforce the isize size limit.
Layout::from_size_valid_align(size, self.align)
Layout::from_size_alignment(size, self.align)
}
/// Creates a layout describing the record for `self` followed by
@ -414,7 +414,7 @@ impl Layout {
pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> {
let new_size = self.size().checked_add(next.size()).ok_or(LayoutError)?;
// The safe constructor is called here to enforce the isize size limit.
Layout::from_size_valid_align(new_size, self.align)
Layout::from_size_alignment(new_size, self.align)
}
/// Creates a layout describing the record for a `[T; n]`.
@ -425,10 +425,10 @@ impl Layout {
#[inline]
pub fn array<T>(n: usize) -> Result<Self, LayoutError> {
// Reduce the amount of code we need to monomorphize per `T`.
return inner(mem::size_of::<T>(), ValidAlign::of::<T>(), n);
return inner(mem::size_of::<T>(), Alignment::of::<T>(), n);
#[inline]
fn inner(element_size: usize, align: ValidAlign, n: usize) -> Result<Layout, LayoutError> {
fn inner(element_size: usize, align: Alignment, n: usize) -> Result<Layout, LayoutError> {
// We need to check two things about the size:
// - That the total size won't overflow a `usize`, and
// - That the total size still fits in an `isize`.
@ -443,7 +443,7 @@ impl Layout {
// SAFETY: We just checked above that the `array_size` will not
// exceed `isize::MAX` even when rounded up to the alignment.
// And `ValidAlign` guarantees it's a power of two.
// And `Alignment` guarantees it's a power of two.
unsafe { Ok(Layout::from_size_align_unchecked(array_size, align.as_usize())) }
}
}

View file

@ -21,11 +21,6 @@ mod maybe_uninit;
#[stable(feature = "maybe_uninit", since = "1.36.0")]
pub use maybe_uninit::MaybeUninit;
// FIXME: This is left here for now to avoid complications around pending reverts.
// Once <https://github.com/rust-lang/rust/issues/101899> is fully resolved,
// this should be removed and the references in `alloc::Layout` updated.
pub(crate) use ptr::Alignment as ValidAlign;
mod transmutability;
#[unstable(feature = "transmutability", issue = "99571")]
pub use transmutability::{Assume, BikeshedIntrinsicFrom};

View file

@ -107,6 +107,9 @@ macro_rules! int_impl {
/// Returns the number of leading zeros in the binary representation of `self`.
///
/// Depending on what you're doing with the value, you might also be interested in the
/// [`ilog2`] function which returns a consistent number, even if the type widens.
///
/// # Examples
///
/// Basic usage:
@ -116,6 +119,7 @@ macro_rules! int_impl {
///
/// assert_eq!(n.leading_zeros(), 0);
/// ```
#[doc = concat!("[`ilog2`]: ", stringify!($SelfT), "::ilog2")]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
#[must_use = "this returns the result of the operation, \

View file

@ -109,6 +109,9 @@ macro_rules! uint_impl {
/// Returns the number of leading zeros in the binary representation of `self`.
///
/// Depending on what you're doing with the value, you might also be interested in the
/// [`ilog2`] function which returns a consistent number, even if the type widens.
///
/// # Examples
///
/// Basic usage:
@ -118,6 +121,7 @@ macro_rules! uint_impl {
///
/// assert_eq!(n.leading_zeros(), 2);
/// ```
#[doc = concat!("[`ilog2`]: ", stringify!($SelfT), "::ilog2")]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_math", since = "1.32.0")]
#[must_use = "this returns the result of the operation, \

View file

@ -183,8 +183,6 @@ h4.code-header {
font-weight: 600;
margin: 0;
padding: 0;
/* position notable traits in mobile mode within the header */
position: relative;
}
#crate-search,

View file

@ -160,10 +160,6 @@ details.rustdoc-toggle > summary::before {
color: #788797;
}
.search-failed a {
color: #39AFD7;
}
.tooltip::after {
background-color: #314559;
color: #c5c5c5;

View file

@ -82,10 +82,6 @@ details.rustdoc-toggle > summary::before {
filter: invert(100%);
}
.search-failed a {
color: #0089ff;
}
.tooltip::after {
background-color: #000;
color: #fff;

View file

@ -69,17 +69,12 @@
--crate-search-hover-border: #717171;
}
.content .item-info::before { color: #ccc; }
body.source .example-wrap pre.rust a {
background: #eee;
}
.search-failed a {
color: #3873AD;
}
.tooltip::after {
background-color: #000;
color: #fff;

View file

@ -0,0 +1,36 @@
// The goal of this test is to check the color of the "no result" links.
goto: "file://" + |DOC_PATH| + "/lib2/index.html?search=sdkfskjfsdks"
show-text: true
define-function: (
"check-no-result",
(theme, link, link_hover),
[
// Changing theme.
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
("reload"),
("wait-for", "#results"),
("assert", ".search-failed.active"),
("assert-css", ("#results a", {"color": |link|}, ALL)),
("move-cursor-to", "#results a"),
("assert-css", ("#results a:hover", {"color": |link_hover|})),
// Moving the cursor to some other place to not create issues with next function run.
("move-cursor-to", ".search-input"),
]
)
call-function: ("check-no-result", {
"theme": "ayu",
"link": "rgb(57, 175, 215)",
"link_hover": "rgb(57, 175, 215)",
})
call-function: ("check-no-result", {
"theme": "dark",
"link": "rgb(210, 153, 29)",
"link_hover": "rgb(210, 153, 29)",
})
call-function: ("check-no-result", {
"theme": "light",
"link": "rgb(56, 115, 173)",
"link_hover": "rgb(56, 115, 173)",
})

View file

@ -9,3 +9,8 @@ assert-css: (".impl.has-srclink .code-header", {"font-size": "18px", "font-weigh
// Check the impl items.
assert-css: (".impl-items .has-srclink .srclink", {"font-size": "16px", "font-weight": 400}, ALL)
assert-css: (".impl-items .has-srclink .code-header", {"font-size": "16px", "font-weight": 600}, ALL)
// Check that we can click on source link
store-document-property: (url, "URL")
click: ".impl-items .has-srclink .srclink"
assert-document-property-false: {"URL": |url|}

View file

@ -0,0 +1,25 @@
pub trait Foo {
type T;
}
impl Foo for i32 {
type T = f32;
}
pub struct U<T1, T2>(T1, S<T2>)
where
T1: Foo<T = T2>;
pub struct S<T>(T);
fn main() {
// The error message here isn't great -- it has to do with the fact that the
// `expected_inputs_for_expected_output` deduced inputs differs from the inputs
// that we infer from the constraints of the signature.
//
// I am not really sure what the best way of presenting this error message is,
// since right now it just suggests changing `3u32` <=> `3f32` back and forth.
let _: U<_, u32> = U(1, S(3u32));
//~^ ERROR mismatched types
//~| ERROR mismatched types
}

View file

@ -0,0 +1,30 @@
error[E0308]: mismatched types
--> $DIR/formal-and-expected-differ.rs:22:29
|
LL | let _: U<_, u32> = U(1, S(3u32));
| - ^^^^^^^ expected `f32`, found `u32`
| |
| arguments to this struct are incorrect
|
= note: expected struct `S<f32>`
found struct `S<u32>`
note: tuple struct defined here
--> $DIR/formal-and-expected-differ.rs:9:12
|
LL | pub struct U<T1, T2>(T1, S<T2>)
| ^
error[E0308]: mismatched types
--> $DIR/formal-and-expected-differ.rs:22:24
|
LL | let _: U<_, u32> = U(1, S(3u32));
| --------- ^^^^^^^^^^^^^ expected `u32`, found `f32`
| |
| expected due to this
|
= note: expected struct `U<_, u32>`
found struct `U<i32, f32>`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,6 +1,5 @@
// build-pass
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
pub trait A {}
pub trait B {}

View file

@ -0,0 +1,32 @@
// needs-sanitizer-support
// needs-sanitizer-memory
//
// revisions: unoptimized optimized
//
// [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
// [unoptimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins
//
// run-pass
//
// This test case intentionally limits the usage of the std,
// since it will be linked with an uninstrumented version of it.
#![feature(core_intrinsics)]
#![feature(start)]
#![allow(invalid_value)]
use std::hint::black_box;
fn calling_black_box_on_zst_ok() {
// It's OK to call black_box on a value of a zero-sized type, even if its
// underlying the memory location is uninitialized. For non-zero-sized types,
// this would be an MSAN error.
let zst = ();
black_box(zst);
}
#[start]
fn main(_: isize, _: *const *const u8) -> isize {
calling_black_box_on_zst_ok();
0
}

View file

@ -0,0 +1,6 @@
fn main() {
let _: f64 = 0..10; //~ ERROR mismatched types
let _: f64 = 1..; //~ ERROR mismatched types
let _: f64 = ..10; //~ ERROR mismatched types
let _: f64 = std::ops::Range { start: 0, end: 1 }; //~ ERROR mismatched types
}

View file

@ -0,0 +1,59 @@
error[E0308]: mismatched types
--> $DIR/unnecessary_dot_for_floating_point_literal.rs:2:18
|
LL | let _: f64 = 0..10;
| --- ^^^^^ expected `f64`, found struct `std::ops::Range`
| |
| expected due to this
|
= note: expected type `f64`
found struct `std::ops::Range<{integer}>`
help: remove the unnecessary `.` operator for a floating point literal
|
LL | let _: f64 = 0.10;
| ~
error[E0308]: mismatched types
--> $DIR/unnecessary_dot_for_floating_point_literal.rs:3:18
|
LL | let _: f64 = 1..;
| --- ^^^ expected `f64`, found struct `RangeFrom`
| |
| expected due to this
|
= note: expected type `f64`
found struct `RangeFrom<{integer}>`
help: remove the unnecessary `.` operator for a floating point literal
|
LL | let _: f64 = 1.;
| ~
error[E0308]: mismatched types
--> $DIR/unnecessary_dot_for_floating_point_literal.rs:4:18
|
LL | let _: f64 = ..10;
| --- ^^^^ expected `f64`, found struct `RangeTo`
| |
| expected due to this
|
= note: expected type `f64`
found struct `RangeTo<{integer}>`
help: remove the unnecessary `.` operator and add an integer part for a floating point literal
|
LL | let _: f64 = 0.10;
| ~~
error[E0308]: mismatched types
--> $DIR/unnecessary_dot_for_floating_point_literal.rs:5:18
|
LL | let _: f64 = std::ops::Range { start: 0, end: 1 };
| --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `f64`, found struct `std::ops::Range`
| |
| expected due to this
|
= note: expected type `f64`
found struct `std::ops::Range<{integer}>`
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,7 +1,6 @@
// run-pass
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
fn a(&self) -> i32 {

View file

@ -1,6 +1,5 @@
// run-pass
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
trait Foo<T: Default + ToString>: Bar<i32> + Bar<T> {}
trait Bar<T: Default + ToString> {

View file

@ -1,7 +1,6 @@
// run-pass
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
fn a(&self) -> i32 {

View file

@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
trait Foo {
fn a(&self) -> i32 {

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:54:35
--> $DIR/invalid-upcast.rs:53:35
|
LL | let _: &dyn std::fmt::Debug = baz;
| -------------------- ^^^ expected trait `Debug`, found trait `Baz`
@ -10,7 +10,7 @@ LL | let _: &dyn std::fmt::Debug = baz;
found reference `&dyn Baz`
error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:56:24
--> $DIR/invalid-upcast.rs:55:24
|
LL | let _: &dyn Send = baz;
| --------- ^^^ expected trait `Send`, found trait `Baz`
@ -21,7 +21,7 @@ LL | let _: &dyn Send = baz;
found reference `&dyn Baz`
error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:58:24
--> $DIR/invalid-upcast.rs:57:24
|
LL | let _: &dyn Sync = baz;
| --------- ^^^ expected trait `Sync`, found trait `Baz`
@ -32,7 +32,7 @@ LL | let _: &dyn Sync = baz;
found reference `&dyn Baz`
error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:61:25
--> $DIR/invalid-upcast.rs:60:25
|
LL | let bar: &dyn Bar = baz;
| -------- ^^^ expected trait `Bar`, found trait `Baz`
@ -43,7 +43,7 @@ LL | let bar: &dyn Bar = baz;
found reference `&dyn Baz`
error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:63:35
--> $DIR/invalid-upcast.rs:62:35
|
LL | let _: &dyn std::fmt::Debug = bar;
| -------------------- ^^^ expected trait `Debug`, found trait `Bar`
@ -54,7 +54,7 @@ LL | let _: &dyn std::fmt::Debug = bar;
found reference `&dyn Bar`
error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:65:24
--> $DIR/invalid-upcast.rs:64:24
|
LL | let _: &dyn Send = bar;
| --------- ^^^ expected trait `Send`, found trait `Bar`
@ -65,7 +65,7 @@ LL | let _: &dyn Send = bar;
found reference `&dyn Bar`
error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:67:24
--> $DIR/invalid-upcast.rs:66:24
|
LL | let _: &dyn Sync = bar;
| --------- ^^^ expected trait `Sync`, found trait `Bar`
@ -76,7 +76,7 @@ LL | let _: &dyn Sync = bar;
found reference `&dyn Bar`
error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:70:25
--> $DIR/invalid-upcast.rs:69:25
|
LL | let foo: &dyn Foo = baz;
| -------- ^^^ expected trait `Foo`, found trait `Baz`
@ -87,7 +87,7 @@ LL | let foo: &dyn Foo = baz;
found reference `&dyn Baz`
error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:72:35
--> $DIR/invalid-upcast.rs:71:35
|
LL | let _: &dyn std::fmt::Debug = foo;
| -------------------- ^^^ expected trait `Debug`, found trait `Foo`
@ -98,7 +98,7 @@ LL | let _: &dyn std::fmt::Debug = foo;
found reference `&dyn Foo`
error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:74:24
--> $DIR/invalid-upcast.rs:73:24
|
LL | let _: &dyn Send = foo;
| --------- ^^^ expected trait `Send`, found trait `Foo`
@ -109,7 +109,7 @@ LL | let _: &dyn Send = foo;
found reference `&dyn Foo`
error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:76:24
--> $DIR/invalid-upcast.rs:75:24
|
LL | let _: &dyn Sync = foo;
| --------- ^^^ expected trait `Sync`, found trait `Foo`
@ -120,7 +120,7 @@ LL | let _: &dyn Sync = foo;
found reference `&dyn Foo`
error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:79:25
--> $DIR/invalid-upcast.rs:78:25
|
LL | let foo: &dyn Foo = bar;
| -------- ^^^ expected trait `Foo`, found trait `Bar`
@ -131,7 +131,7 @@ LL | let foo: &dyn Foo = bar;
found reference `&dyn Bar`
error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:81:35
--> $DIR/invalid-upcast.rs:80:35
|
LL | let _: &dyn std::fmt::Debug = foo;
| -------------------- ^^^ expected trait `Debug`, found trait `Foo`
@ -142,7 +142,7 @@ LL | let _: &dyn std::fmt::Debug = foo;
found reference `&dyn Foo`
error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:83:24
--> $DIR/invalid-upcast.rs:82:24
|
LL | let _: &dyn Send = foo;
| --------- ^^^ expected trait `Send`, found trait `Foo`
@ -153,7 +153,7 @@ LL | let _: &dyn Send = foo;
found reference `&dyn Foo`
error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:85:24
--> $DIR/invalid-upcast.rs:84:24
|
LL | let _: &dyn Sync = foo;
| --------- ^^^ expected trait `Sync`, found trait `Foo`

View file

@ -1,6 +1,5 @@
// run-pass
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
struct Test {
func: Box<dyn FnMut() + 'static>,

View file

@ -1,7 +1,6 @@
// run-pass
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
fn a(&self) -> i32 {

View file

@ -1,12 +1,11 @@
// check-fail
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
trait Bar<T> {
fn bar(&self, _: T) {}
}
trait Foo : Bar<i32> + Bar<u32> {
trait Foo: Bar<i32> + Bar<u32> {
fn foo(&self, _: ()) {}
}

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types
--> $DIR/multiple-occurrence-ambiguousity.rs:21:26
--> $DIR/multiple-occurrence-ambiguousity.rs:20:26
|
LL | let t: &dyn Bar<_> = s;
| ----------- ^ expected trait `Bar`, found trait `Foo`

View file

@ -1,7 +1,6 @@
// run-pass
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
trait A {
fn foo_a(&self);

View file

@ -1,7 +1,6 @@
// run-pass
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
use std::rc::Rc;
use std::sync::Arc;

View file

@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
fn a(&self) -> i32 {

View file

@ -1,64 +1,64 @@
error[E0599]: no method named `c` found for reference `&dyn Bar` in the current scope
--> $DIR/subtrait-method.rs:56:9
--> $DIR/subtrait-method.rs:55:9
|
LL | bar.c();
| ^ help: there is a method with a similar name: `a`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Baz` defines an item `c`, perhaps you need to implement it
--> $DIR/subtrait-method.rs:28:1
--> $DIR/subtrait-method.rs:27:1
|
LL | trait Baz: Bar {
| ^^^^^^^^^^^^^^
error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope
--> $DIR/subtrait-method.rs:60:9
--> $DIR/subtrait-method.rs:59:9
|
LL | foo.b();
| ^ help: there is a method with a similar name: `a`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Bar` defines an item `b`, perhaps you need to implement it
--> $DIR/subtrait-method.rs:18:1
--> $DIR/subtrait-method.rs:17:1
|
LL | trait Bar: Foo {
| ^^^^^^^^^^^^^^
error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope
--> $DIR/subtrait-method.rs:62:9
--> $DIR/subtrait-method.rs:61:9
|
LL | foo.c();
| ^ help: there is a method with a similar name: `a`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Baz` defines an item `c`, perhaps you need to implement it
--> $DIR/subtrait-method.rs:28:1
--> $DIR/subtrait-method.rs:27:1
|
LL | trait Baz: Bar {
| ^^^^^^^^^^^^^^
error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope
--> $DIR/subtrait-method.rs:66:9
--> $DIR/subtrait-method.rs:65:9
|
LL | foo.b();
| ^ help: there is a method with a similar name: `a`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Bar` defines an item `b`, perhaps you need to implement it
--> $DIR/subtrait-method.rs:18:1
--> $DIR/subtrait-method.rs:17:1
|
LL | trait Bar: Foo {
| ^^^^^^^^^^^^^^
error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope
--> $DIR/subtrait-method.rs:68:9
--> $DIR/subtrait-method.rs:67:9
|
LL | foo.c();
| ^ help: there is a method with a similar name: `a`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Baz` defines an item `c`, perhaps you need to implement it
--> $DIR/subtrait-method.rs:28:1
--> $DIR/subtrait-method.rs:27:1
|
LL | trait Baz: Bar {
| ^^^^^^^^^^^^^^

View file

@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
trait Foo: Bar<i32> + Bar<u32> {}
trait Bar<T> {

View file

@ -1,5 +1,5 @@
error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
--> $DIR/type-checking-test-1.rs:17:13
--> $DIR/type-checking-test-1.rs:16:13
|
LL | let _ = x as &dyn Bar<_>; // Ambiguous
| ^^^^^^^^^^^^^^^^ invalid cast
@ -10,7 +10,7 @@ LL | let _ = &x as &dyn Bar<_>; // Ambiguous
| +
error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied
--> $DIR/type-checking-test-1.rs:17:13
--> $DIR/type-checking-test-1.rs:16:13
|
LL | let _ = x as &dyn Bar<_>; // Ambiguous
| ^ the trait `Bar<_>` is not implemented for `&dyn Foo`

View file

@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
trait Foo<T>: Bar<i32> + Bar<T> {}
trait Bar<T> {

View file

@ -1,5 +1,5 @@
error[E0605]: non-primitive cast: `&dyn Foo<i32>` as `&dyn Bar<u32>`
--> $DIR/type-checking-test-2.rs:20:13
--> $DIR/type-checking-test-2.rs:19:13
|
LL | let _ = x as &dyn Bar<u32>; // Error
| ^^^^^^^^^^^^^^^^^^ invalid cast
@ -10,7 +10,7 @@ LL | let _ = &x as &dyn Bar<u32>; // Error
| +
error[E0277]: the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied
--> $DIR/type-checking-test-2.rs:20:13
--> $DIR/type-checking-test-2.rs:19:13
|
LL | let _ = x as &dyn Bar<u32>; // Error
| ^ the trait `Bar<u32>` is not implemented for `&dyn Foo<i32>`
@ -18,7 +18,7 @@ LL | let _ = x as &dyn Bar<u32>; // Error
= note: required for the cast from `&dyn Foo<i32>` to the object type `dyn Bar<u32>`
error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<_>`
--> $DIR/type-checking-test-2.rs:26:13
--> $DIR/type-checking-test-2.rs:25:13
|
LL | let a = x as &dyn Bar<_>; // Ambiguous
| ^^^^^^^^^^^^^^^^ invalid cast
@ -29,7 +29,7 @@ LL | let a = &x as &dyn Bar<_>; // Ambiguous
| +
error[E0277]: the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied
--> $DIR/type-checking-test-2.rs:26:13
--> $DIR/type-checking-test-2.rs:25:13
|
LL | let a = x as &dyn Bar<_>; // Ambiguous
| ^ the trait `Bar<_>` is not implemented for `&dyn Foo<u32>`

View file

@ -1,22 +1,18 @@
error: lifetime may not live long enough
--> $DIR/type-checking-test-3.rs:13:13
--> $DIR/type-checking-test-3.rs:11:13
|
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here
LL | let _ = x as &dyn Bar<'a>; // Error
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
= help: consider replacing `'a` with `'static`
error: lifetime may not live long enough
--> $DIR/type-checking-test-3.rs:18:13
--> $DIR/type-checking-test-3.rs:16:13
|
LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) {
| -- lifetime `'a` defined here
LL | let _ = x as &dyn Bar<'static>; // Error
| ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
= help: consider replacing `'a` with `'static`
error: aborting due to 2 previous errors

View file

@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
trait Foo<'a>: Bar<'a> {}
trait Bar<'a> {}
@ -10,12 +9,12 @@ fn test_correct(x: &dyn Foo<'static>) {
fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
let _ = x as &dyn Bar<'a>; // Error
//~^ ERROR lifetime may not live long enough
//~^ ERROR lifetime may not live long enough
}
fn test_wrong2<'a>(x: &dyn Foo<'a>) {
let _ = x as &dyn Bar<'static>; // Error
//~^ ERROR lifetime may not live long enough
//~^ ERROR lifetime may not live long enough
}
fn main() {}

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/type-checking-test-3.rs:12:13
--> $DIR/type-checking-test-3.rs:11:13
|
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here
@ -7,7 +7,7 @@ LL | let _ = x as &dyn Bar<'a>; // Error
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/type-checking-test-3.rs:17:13
--> $DIR/type-checking-test-3.rs:16:13
|
LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) {
| -- lifetime `'a` defined here

View file

@ -1,33 +1,52 @@
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:17:13
--> $DIR/type-checking-test-4.rs:15:13
|
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here
LL | let _ = x as &dyn Bar<'static, 'a>; // Error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
= help: consider replacing `'a` with `'static`
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:22:13
--> $DIR/type-checking-test-4.rs:20:13
|
LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here
LL | let _ = x as &dyn Bar<'a, 'static>; // Error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
= help: consider replacing `'a` with `'static`
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:29:5
--> $DIR/type-checking-test-4.rs:26:5
|
LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
...
LL | let y = x as &dyn Bar<'_, '_>;
LL | y.get_b() // ERROR
| ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:31:5
|
= help: consider replacing `'a` with `'static`
LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
LL | <_ as Bar>::get_b(x) // ERROR
| ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: aborting due to 3 previous errors
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:36:5
|
LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:44:5
|
LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
...
LL | z.get_b() // ERROR
| ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: aborting due to 6 previous errors

View file

@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
trait Foo<'a>: Bar<'a, 'a> {}
trait Bar<'a, 'b> {
@ -14,28 +13,28 @@ fn test_correct(x: &dyn Foo<'static>) {
fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
let _ = x as &dyn Bar<'static, 'a>; // Error
//~^ ERROR lifetime may not live long enough
//~^ ERROR lifetime may not live long enough
}
fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
let _ = x as &dyn Bar<'a, 'static>; // Error
//~^ ERROR lifetime may not live long enough
//~^ ERROR lifetime may not live long enough
}
fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
let y = x as &dyn Bar<'_, '_>;
y.get_b() // ERROR
//~^ ERROR lifetime may not live long enough
//~^ ERROR lifetime may not live long enough
}
fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
<_ as Bar>::get_b(x) // ERROR
//~^ ERROR lifetime may not live long enough
//~^ ERROR lifetime may not live long enough
}
fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
<_ as Bar<'_, '_>>::get_b(x) // ERROR
//~^ ERROR lifetime may not live long enough
//~^ ERROR lifetime may not live long enough
}
fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
@ -43,7 +42,7 @@ fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
y.get_b(); // ERROR
let z = y;
z.get_b() // ERROR
//~^ ERROR lifetime may not live long enough
//~^ ERROR lifetime may not live long enough
}
fn main() {}

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:16:13
--> $DIR/type-checking-test-4.rs:15:13
|
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here
@ -7,7 +7,7 @@ LL | let _ = x as &dyn Bar<'static, 'a>; // Error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:21:13
--> $DIR/type-checking-test-4.rs:20:13
|
LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here
@ -15,7 +15,7 @@ LL | let _ = x as &dyn Bar<'a, 'static>; // Error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:27:5
--> $DIR/type-checking-test-4.rs:26:5
|
LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
@ -24,7 +24,7 @@ LL | y.get_b() // ERROR
| ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:32:5
--> $DIR/type-checking-test-4.rs:31:5
|
LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
@ -32,7 +32,7 @@ LL | <_ as Bar>::get_b(x) // ERROR
| ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:37:5
--> $DIR/type-checking-test-4.rs:36:5
|
LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
@ -40,7 +40,7 @@ LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:45:5
--> $DIR/type-checking-test-4.rs:44:5
|
LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here