Skip to content

Rollup of 8 pull requests #104324

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 24 commits into from
Closed
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0e0bcd9
prevent uninitialized access in black_box for zero-sized-types
krasimirgg Nov 4, 2022
3074678
Mark `trait_upcasting` feature no longer incomplete.
crlf0710 Nov 7, 2022
312d6b8
Don't emit coerce suggestions for a type into itself
compiler-errors Nov 10, 2022
55f1f99
More accurately report error when formal and expected signature types…
compiler-errors Nov 10, 2022
d85b614
Add a reference to ilog2 in leading_zeros integer docs
albertlarsan68 Nov 10, 2022
c467006
suggest removing unnecessary . to use a floating point literal
TaKO8Ki Nov 8, 2022
004986b
avoid unnecessary `format!`
TaKO8Ki Nov 8, 2022
6018f11
emit errors when using `RangeFrom` and `RangeTo`
TaKO8Ki Nov 9, 2022
fb98796
Apply suggestions
albertlarsan68 Nov 11, 2022
a1909b7
Try another way
albertlarsan68 Nov 11, 2022
fed1053
Remove the old `ValidAlign` name
scottmcm Nov 12, 2022
18c4fa6
Migrate no result page link color to CSS variables
GuillaumeGomez Nov 10, 2022
7e79619
Add GUI test for "no result found" links
GuillaumeGomez Nov 10, 2022
ee73812
Use same color for links in no result search
GuillaumeGomez Nov 11, 2022
35c3ca2
Fix impossibility to click on source link
GuillaumeGomez Nov 12, 2022
c645d3e
Add GUI test to ensure that source links can be clicked
GuillaumeGomez Nov 12, 2022
3b91f01
Rollup merge of #104110 - krasimirgg:msan-16, r=nagisa
GuillaumeGomez Nov 12, 2022
c655cbf
Rollup merge of #104117 - crlf0710:update_feature_gate, r=jackh726
GuillaumeGomez Nov 12, 2022
02ef4f2
Rollup merge of #104144 - TaKO8Ki:suggest-removing-unnecessary-dot, r…
GuillaumeGomez Nov 12, 2022
561007a
Rollup merge of #104250 - GuillaumeGomez:migrate-not-found-link-color…
GuillaumeGomez Nov 12, 2022
c2389a1
Rollup merge of #104261 - compiler-errors:formal-and-expected-differ,…
GuillaumeGomez Nov 12, 2022
338ca5c
Rollup merge of #104263 - albertlarsan68:add-ilog2-to-leading-zeroes-…
GuillaumeGomez Nov 12, 2022
ac21592
Rollup merge of #104308 - scottmcm:no-more-validalign, r=thomcc
GuillaumeGomez Nov 12, 2022
669155c
Rollup merge of #104319 - GuillaumeGomez:fix-non-clickable-source-lin…
GuillaumeGomez Nov 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
@@ -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,
6 changes: 3 additions & 3 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
@@ -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.
7 changes: 6 additions & 1 deletion compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
@@ -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);
29 changes: 18 additions & 11 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
@@ -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,
44 changes: 43 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
@@ -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(..), .. }))
28 changes: 14 additions & 14 deletions library/core/src/alloc/layout.rs
Original file line number Diff line number Diff line change
@@ -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())) }
}
}
5 changes: 0 additions & 5 deletions library/core/src/mem/mod.rs
Original file line number Diff line number Diff line change
@@ -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};
4 changes: 4 additions & 0 deletions library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
@@ -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, \
4 changes: 4 additions & 0 deletions library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
@@ -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, \
2 changes: 0 additions & 2 deletions src/librustdoc/html/static/css/rustdoc.css
Original file line number Diff line number Diff line change
@@ -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,
4 changes: 0 additions & 4 deletions src/librustdoc/html/static/css/themes/ayu.css
Original file line number Diff line number Diff line change
@@ -160,10 +160,6 @@ details.rustdoc-toggle > summary::before {
color: #788797;
}

.search-failed a {
color: #39AFD7;
}

.tooltip::after {
background-color: #314559;
color: #c5c5c5;
4 changes: 0 additions & 4 deletions src/librustdoc/html/static/css/themes/dark.css
Original file line number Diff line number Diff line change
@@ -82,10 +82,6 @@ details.rustdoc-toggle > summary::before {
filter: invert(100%);
}

.search-failed a {
color: #0089ff;
}

.tooltip::after {
background-color: #000;
color: #fff;
5 changes: 0 additions & 5 deletions src/librustdoc/html/static/css/themes/light.css
Original file line number Diff line number Diff line change
@@ -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;
36 changes: 36 additions & 0 deletions src/test/rustdoc-gui/search-no-result.goml
Original file line number Diff line number Diff line change
@@ -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)",
})
5 changes: 5 additions & 0 deletions src/test/rustdoc-gui/src-font-size.goml
Original file line number Diff line number Diff line change
@@ -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|}
25 changes: 25 additions & 0 deletions src/test/ui/argument-suggestions/formal-and-expected-differ.rs
Original file line number Diff line number Diff line change
@@ -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
}
30 changes: 30 additions & 0 deletions src/test/ui/argument-suggestions/formal-and-expected-differ.stderr
Original file line number Diff line number Diff line change
@@ -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`.
1 change: 0 additions & 1 deletion src/test/ui/codegen/issue-99551.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// build-pass
#![feature(trait_upcasting)]
#![allow(incomplete_features)]

pub trait A {}
pub trait B {}
32 changes: 32 additions & 0 deletions src/test/ui/sanitize/memory-passing.rs
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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`.
1 change: 0 additions & 1 deletion src/test/ui/traits/trait-upcasting/basic.rs
Original file line number Diff line number Diff line change
@@ -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 {
Original file line number Diff line number Diff line change
@@ -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> {
1 change: 0 additions & 1 deletion src/test/ui/traits/trait-upcasting/diamond.rs
Original file line number Diff line number Diff line change
@@ -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 {
1 change: 0 additions & 1 deletion src/test/ui/traits/trait-upcasting/invalid-upcast.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
#![allow(incomplete_features)]

trait Foo {
fn a(&self) -> i32 {
30 changes: 15 additions & 15 deletions src/test/ui/traits/trait-upcasting/invalid-upcast.stderr
Original file line number Diff line number Diff line change
@@ -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`
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// run-pass
#![feature(trait_upcasting)]
#![allow(incomplete_features)]

struct Test {
func: Box<dyn FnMut() + 'static>,
1 change: 0 additions & 1 deletion src/test/ui/traits/trait-upcasting/lifetime.rs
Original file line number Diff line number Diff line change
@@ -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 {
Original file line number Diff line number Diff line change
@@ -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, _: ()) {}
}

Original file line number Diff line number Diff line change
@@ -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`
1 change: 0 additions & 1 deletion src/test/ui/traits/trait-upcasting/replace-vptr.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// run-pass

#![feature(trait_upcasting)]
#![allow(incomplete_features)]

trait A {
fn foo_a(&self);
1 change: 0 additions & 1 deletion src/test/ui/traits/trait-upcasting/struct.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// run-pass

#![feature(trait_upcasting)]
#![allow(incomplete_features)]

use std::rc::Rc;
use std::sync::Arc;
1 change: 0 additions & 1 deletion src/test/ui/traits/trait-upcasting/subtrait-method.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
#![allow(incomplete_features)]

trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
fn a(&self) -> i32 {
20 changes: 10 additions & 10 deletions src/test/ui/traits/trait-upcasting/subtrait-method.stderr
Original file line number Diff line number Diff line change
@@ -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 {
| ^^^^^^^^^^^^^^
1 change: 0 additions & 1 deletion src/test/ui/traits/trait-upcasting/type-checking-test-1.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
#![allow(incomplete_features)]

trait Foo: Bar<i32> + Bar<u32> {}
trait Bar<T> {
Original file line number Diff line number Diff line change
@@ -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`
1 change: 0 additions & 1 deletion src/test/ui/traits/trait-upcasting/type-checking-test-2.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
#![allow(incomplete_features)]

trait Foo<T>: Bar<i32> + Bar<T> {}
trait Bar<T> {
Original file line number Diff line number Diff line change
@@ -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,15 +10,15 @@ 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>`
|
= 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>`
Original file line number Diff line number Diff line change
@@ -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

5 changes: 2 additions & 3 deletions src/test/ui/traits/trait-upcasting/type-checking-test-3.rs
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
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
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
Original file line number Diff line number Diff line change
@@ -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
|
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: 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
|
= help: consider replacing `'a` with `'static`
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 3 previous errors
error: aborting due to 6 previous errors

13 changes: 6 additions & 7 deletions src/test/ui/traits/trait-upcasting/type-checking-test-4.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
#![allow(incomplete_features)]

trait Foo<'a>: Bar<'a, 'a> {}
trait Bar<'a, 'b> {
@@ -14,36 +13,36 @@ 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> {
let y = x as &dyn Bar<'_, '_>;
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() {}
12 changes: 6 additions & 6 deletions src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
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
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
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,23 +24,23 @@ 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
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
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