Skip to content

Rollup of 7 pull requests #117294

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

Merged
merged 18 commits into from
Oct 27, 2023
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
f4a9d29
Remove `rustc_symbol_mangling/messages.ftl`.
nnethercote Oct 17, 2023
041f031
Properly restore snapshot when failing to recover parsing ternary
clubby789 Oct 26, 2023
3bbc70a
Restrict param constraint suggestion
estebank Oct 26, 2023
84c9c4a
NVPTX: Allow PassMode::Direct for ptx kernels for now
kjetilkjeka Oct 26, 2023
4d33876
Documentation and error message improvements related to PassMode::Dir…
kjetilkjeka Oct 26, 2023
e81a5c6
Recover ternary expression as error
clubby789 Oct 26, 2023
72d5f4b
Hide internal methods from documentation
jhpratt Oct 27, 2023
bb45c81
Link to correct issue in PassMode::Direct ptx-kernel exception
Oct 27, 2023
ccb36a6
std::thread: add SAFETY comment
RalfJung Oct 27, 2023
b915fc8
fix miri target information for Test step
onur-ozkan Oct 27, 2023
7449478
Account for type param from other item in `note_and_explain`
estebank Oct 26, 2023
df8852a
Rollup merge of #116834 - nnethercote:rustc_symbol_mangling, r=davidtwco
matthiaskrgr Oct 27, 2023
b229537
Rollup merge of #117212 - clubby789:fix-ternary-recover, r=compiler-e…
matthiaskrgr Oct 27, 2023
a77f743
Rollup merge of #117246 - estebank:issue-117209, r=petrochenkov
matthiaskrgr Oct 27, 2023
c3d56be
Rollup merge of #117247 - kjetilkjeka:nvptx_direct_passmode_exception…
matthiaskrgr Oct 27, 2023
60b071f
Rollup merge of #117270 - jhpratt:hide-print-internals, r=ChrisDenton
matthiaskrgr Oct 27, 2023
f9d62a8
Rollup merge of #117281 - RalfJung:thread-safety, r=thomcc
matthiaskrgr Oct 27, 2023
b9015da
Rollup merge of #117287 - onur-ozkan:fix-miri-target-info, r=RalfJung
matthiaskrgr Oct 27, 2023
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
2 changes: 0 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -4557,9 +4557,7 @@ dependencies = [
"rustc-demangle",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
"rustc_hir",
"rustc_macros",
"rustc_middle",
"rustc_session",
"rustc_span",
9 changes: 7 additions & 2 deletions compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
@@ -362,9 +362,14 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
// currently use this mode so we have to allow it -- but we absolutely
// shouldn't let any more targets do that.
// (Also see <https://github.com/rust-lang/rust/issues/115666>.)
//
// The unstable abi `PtxKernel` also uses Direct for now.
// It needs to switch to something else before stabilization can happen.
// (See issue: https://github.com/rust-lang/rust/issues/117271)
assert!(
matches!(&*cx.tcx.sess.target.arch, "wasm32" | "wasm64"),
"`PassMode::Direct` for aggregates only allowed on wasm targets\nProblematic type: {:#?}",
matches!(&*cx.tcx.sess.target.arch, "wasm32" | "wasm64")
|| self.conv == Conv::PtxKernel,
"`PassMode::Direct` for aggregates only allowed on wasm and `extern \"ptx-kernel\"` fns\nProblematic type: {:#?}",
arg.layout,
);
}
1 change: 0 additions & 1 deletion compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
@@ -136,7 +136,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[
rustc_query_system::DEFAULT_LOCALE_RESOURCE,
rustc_resolve::DEFAULT_LOCALE_RESOURCE,
rustc_session::DEFAULT_LOCALE_RESOURCE,
rustc_symbol_mangling::DEFAULT_LOCALE_RESOURCE,
rustc_trait_selection::DEFAULT_LOCALE_RESOURCE,
rustc_ty_utils::DEFAULT_LOCALE_RESOURCE,
// tidy-alphabetical-end
113 changes: 67 additions & 46 deletions compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
Original file line number Diff line number Diff line change
@@ -54,13 +54,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
(ty::Param(expected), ty::Param(found)) => {
let generics = tcx.generics_of(body_owner_def_id);
let e_span = tcx.def_span(generics.type_param(expected, tcx).def_id);
if !sp.contains(e_span) {
diag.span_label(e_span, "expected type parameter");
if let Some(param) = generics.opt_type_param(expected, tcx) {
let e_span = tcx.def_span(param.def_id);
if !sp.contains(e_span) {
diag.span_label(e_span, "expected type parameter");
}
}
let f_span = tcx.def_span(generics.type_param(found, tcx).def_id);
if !sp.contains(f_span) {
diag.span_label(f_span, "found type parameter");
if let Some(param) = generics.opt_type_param(found, tcx) {
let f_span = tcx.def_span(param.def_id);
if !sp.contains(f_span) {
diag.span_label(f_span, "found type parameter");
}
}
diag.note(
"a type parameter was expected, but a different one was found; \
@@ -83,23 +87,29 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
| (ty::Alias(ty::Projection, proj), ty::Param(p))
if !tcx.is_impl_trait_in_trait(proj.def_id) =>
{
let p_def_id = tcx.generics_of(body_owner_def_id).type_param(p, tcx).def_id;
let p_span = tcx.def_span(p_def_id);
let expected = match (values.expected.kind(), values.found.kind()) {
(ty::Param(_), _) => "expected ",
(_, ty::Param(_)) => "found ",
_ => "",
};
if !sp.contains(p_span) {
diag.span_label(p_span, format!("{expected}this type parameter"));
}
let hir = tcx.hir();
let parent = tcx.generics_of(body_owner_def_id)
.opt_type_param(p, tcx)
.and_then(|param| {
let p_def_id = param.def_id;
let p_span = tcx.def_span(p_def_id);
let expected = match (values.expected.kind(), values.found.kind()) {
(ty::Param(_), _) => "expected ",
(_, ty::Param(_)) => "found ",
_ => "",
};
if !sp.contains(p_span) {
diag.span_label(
p_span,
format!("{expected}this type parameter"),
);
}
p_def_id.as_local().and_then(|id| {
let local_id = tcx.hir().local_def_id_to_hir_id(id);
let generics = tcx.hir().find_parent(local_id)?.generics()?;
Some((id, generics))
})
});
let mut note = true;
let parent = p_def_id.as_local().and_then(|id| {
let local_id = hir.local_def_id_to_hir_id(id);
let generics = tcx.hir().find_parent(local_id)?.generics()?;
Some((id, generics))
});
if let Some((local_id, generics)) = parent {
// Synthesize the associated type restriction `Add<Output = Expected>`.
// FIXME: extract this logic for use in other diagnostics.
@@ -172,14 +182,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
(ty::Param(p), ty::Dynamic(..) | ty::Alias(ty::Opaque, ..))
| (ty::Dynamic(..) | ty::Alias(ty::Opaque, ..), ty::Param(p)) => {
let generics = tcx.generics_of(body_owner_def_id);
let p_span = tcx.def_span(generics.type_param(p, tcx).def_id);
let expected = match (values.expected.kind(), values.found.kind()) {
(ty::Param(_), _) => "expected ",
(_, ty::Param(_)) => "found ",
_ => "",
};
if !sp.contains(p_span) {
diag.span_label(p_span, format!("{expected}this type parameter"));
if let Some(param) = generics.opt_type_param(p, tcx) {
let p_span = tcx.def_span(param.def_id);
let expected = match (values.expected.kind(), values.found.kind()) {
(ty::Param(_), _) => "expected ",
(_, ty::Param(_)) => "found ",
_ => "",
};
if !sp.contains(p_span) {
diag.span_label(p_span, format!("{expected}this type parameter"));
}
}
diag.help("type parameters must be constrained to match other types");
if tcx.sess.teach(&diag.get_code().unwrap()) {
@@ -217,9 +229,11 @@ impl<T> Trait<T> for X {
}
(ty::Param(p), ty::Closure(..) | ty::Coroutine(..)) => {
let generics = tcx.generics_of(body_owner_def_id);
let p_span = tcx.def_span(generics.type_param(p, tcx).def_id);
if !sp.contains(p_span) {
diag.span_label(p_span, "expected this type parameter");
if let Some(param) = generics.opt_type_param(p, tcx) {
let p_span = tcx.def_span(param.def_id);
if !sp.contains(p_span) {
diag.span_label(p_span, "expected this type parameter");
}
}
diag.help(format!(
"every closure has a distinct type and so could not always match the \
@@ -228,14 +242,16 @@ impl<T> Trait<T> for X {
}
(ty::Param(p), _) | (_, ty::Param(p)) => {
let generics = tcx.generics_of(body_owner_def_id);
let p_span = tcx.def_span(generics.type_param(p, tcx).def_id);
let expected = match (values.expected.kind(), values.found.kind()) {
(ty::Param(_), _) => "expected ",
(_, ty::Param(_)) => "found ",
_ => "",
};
if !sp.contains(p_span) {
diag.span_label(p_span, format!("{expected}this type parameter"));
if let Some(param) = generics.opt_type_param(p, tcx) {
let p_span = tcx.def_span(param.def_id);
let expected = match (values.expected.kind(), values.found.kind()) {
(ty::Param(_), _) => "expected ",
(_, ty::Param(_)) => "found ",
_ => "",
};
if !sp.contains(p_span) {
diag.span_label(p_span, format!("{expected}this type parameter"));
}
}
}
(ty::Alias(ty::Projection | ty::Inherent, proj_ty), _)
@@ -364,13 +380,14 @@ impl<T> Trait<T> for X {
};
// Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
// This will also work for `impl Trait`.
let def_id = if let ty::Param(param_ty) = proj_ty.self_ty().kind() {
let generics = tcx.generics_of(body_owner_def_id);
generics.type_param(param_ty, tcx).def_id
} else {
let ty::Param(param_ty) = proj_ty.self_ty().kind() else {
return false;
};
let Some(def_id) = def_id.as_local() else {
let generics = tcx.generics_of(body_owner_def_id);
let Some(param) = generics.opt_type_param(param_ty, tcx) else {
return false;
};
let Some(def_id) = param.def_id.as_local() else {
return false;
};

@@ -390,6 +407,10 @@ impl<T> Trait<T> for X {
return true;
}
}
if (param_ty.index as usize) >= generics.parent_count {
// The param comes from the current item, do not look at the parent. (#117209)
return false;
}
// If associated item, look to constrain the params of the trait/impl.
let hir_id = match item {
hir::Node::ImplItem(item) => item.hir_id(),
28 changes: 28 additions & 0 deletions compiler/rustc_middle/src/ty/generics.rs
Original file line number Diff line number Diff line change
@@ -237,6 +237,20 @@ impl<'tcx> Generics {
}
}

/// Returns the `GenericParamDef` with the given index if available.
pub fn opt_param_at(
&'tcx self,
param_index: usize,
tcx: TyCtxt<'tcx>,
) -> Option<&'tcx GenericParamDef> {
if let Some(index) = param_index.checked_sub(self.parent_count) {
self.params.get(index)
} else {
tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
.opt_param_at(param_index, tcx)
}
}

pub fn params_to(&'tcx self, param_index: usize, tcx: TyCtxt<'tcx>) -> &'tcx [GenericParamDef] {
if let Some(index) = param_index.checked_sub(self.parent_count) {
&self.params[..index]
@@ -268,6 +282,20 @@ impl<'tcx> Generics {
}
}

/// Returns the `GenericParamDef` associated with this `ParamTy` if it belongs to this
/// `Generics`.
pub fn opt_type_param(
&'tcx self,
param: &ParamTy,
tcx: TyCtxt<'tcx>,
) -> Option<&'tcx GenericParamDef> {
let param = self.opt_param_at(param.index as usize, tcx)?;
match param.kind {
GenericParamDefKind::Type { .. } => Some(param),
_ => None,
}
}

/// Returns the `GenericParamDef` associated with this `ParamConst`.
pub fn const_param(&'tcx self, param: &ParamConst, tcx: TyCtxt<'tcx>) -> &GenericParamDef {
let param = self.param_at(param.index as usize, tcx);
26 changes: 13 additions & 13 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -504,8 +504,10 @@ impl<'a> Parser<'a> {

// Special-case "expected `;`" errors
if expected.contains(&TokenType::Token(token::Semi)) {
if self.prev_token == token::Question && self.maybe_recover_from_ternary_operator() {
return Ok(true);
// If the user is trying to write a ternary expression, recover it and
// return an Err to prevent a cascade of irrelevant diagnostics
if self.prev_token == token::Question && let Err(e) = self.maybe_recover_from_ternary_operator() {
return Err(e);
}

if self.token.span == DUMMY_SP || self.prev_token.span == DUMMY_SP {
@@ -1428,10 +1430,10 @@ impl<'a> Parser<'a> {

/// Rust has no ternary operator (`cond ? then : else`). Parse it and try
/// to recover from it if `then` and `else` are valid expressions. Returns
/// whether it was a ternary operator.
pub(super) fn maybe_recover_from_ternary_operator(&mut self) -> bool {
/// an err if this appears to be a ternary expression.
pub(super) fn maybe_recover_from_ternary_operator(&mut self) -> PResult<'a, ()> {
if self.prev_token != token::Question {
return false;
return PResult::Ok(());
}

let lo = self.prev_token.span.lo();
@@ -1449,20 +1451,18 @@ impl<'a> Parser<'a> {
if self.eat_noexpect(&token::Colon) {
match self.parse_expr() {
Ok(_) => {
self.sess.emit_err(TernaryOperator { span: self.token.span.with_lo(lo) });
return true;
return Err(self
.sess
.create_err(TernaryOperator { span: self.token.span.with_lo(lo) }));
}
Err(err) => {
err.cancel();
self.restore_snapshot(snapshot);
}
};
}
} else {
self.restore_snapshot(snapshot);
};

false
}
self.restore_snapshot(snapshot);
Ok(())
}

pub(super) fn maybe_recover_from_bad_type_plus(&mut self, ty: &Ty) -> PResult<'a, ()> {
2 changes: 0 additions & 2 deletions compiler/rustc_symbol_mangling/Cargo.toml
Original file line number Diff line number Diff line change
@@ -15,9 +15,7 @@ twox-hash = "1.6.3"
rustc_span = { path = "../rustc_span" }
rustc_middle = { path = "../rustc_middle" }
rustc_hir = { path = "../rustc_hir" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_target = { path = "../rustc_target" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_session = { path = "../rustc_session" }
rustc_macros = { path = "../rustc_macros" }
rustc_errors = { path = "../rustc_errors" }
1 change: 0 additions & 1 deletion compiler/rustc_symbol_mangling/messages.ftl

This file was deleted.

40 changes: 26 additions & 14 deletions compiler/rustc_symbol_mangling/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,46 @@
//! Errors emitted by symbol_mangling.

use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
use rustc_macros::Diagnostic;
use rustc_errors::{ErrorGuaranteed, IntoDiagnostic};
use rustc_span::Span;
use std::fmt;

#[derive(Diagnostic)]
#[diag(symbol_mangling_test_output)]
pub struct TestOutput {
#[primary_span]
pub span: Span,
pub kind: Kind,
pub content: String,
}

// This diagnostic doesn't need translation because (a) it doesn't contain any
// natural language, and (b) it's only used in tests. So we construct it
// manually and avoid the fluent machinery.
impl IntoDiagnostic<'_> for TestOutput {
fn into_diagnostic(
self,
handler: &'_ rustc_errors::Handler,
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
let TestOutput { span, kind, content } = self;

#[allow(rustc::untranslatable_diagnostic)]
let mut diag = handler.struct_err(format!("{kind}({content})"));
diag.set_span(span);
diag
}
}

pub enum Kind {
SymbolName,
Demangling,
DemanglingAlt,
DefPath,
}

impl IntoDiagnosticArg for Kind {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
let kind = match self {
Kind::SymbolName => "symbol-name",
Kind::Demangling => "demangling",
Kind::DemanglingAlt => "demangling-alt",
Kind::DefPath => "def-path",
impl fmt::Display for Kind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Kind::SymbolName => write!(f, "symbol-name"),
Kind::Demangling => write!(f, "demangling"),
Kind::DemanglingAlt => write!(f, "demangling-alt"),
Kind::DefPath => write!(f, "def-path"),
}
.into();
DiagnosticArgValue::Str(kind)
}
}
4 changes: 0 additions & 4 deletions compiler/rustc_symbol_mangling/src/lib.rs
Original file line number Diff line number Diff line change
@@ -103,8 +103,6 @@ extern crate rustc_middle;
#[macro_use]
extern crate tracing;

use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_fluent_macro::fluent_messages;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
@@ -121,8 +119,6 @@ pub mod errors;
pub mod test;
pub mod typeid;

fluent_messages! { "../messages.ftl" }

/// This function computes the symbol name for the given `instance` and the
/// given instantiating crate. That is, if you know that instance X is
/// instantiated in crate Y, this is the symbol name this instance would have.
1 change: 1 addition & 0 deletions library/std/src/io/mod.rs
Original file line number Diff line number Diff line change
@@ -317,6 +317,7 @@ pub use self::stdio::set_output_capture;
#[stable(feature = "is_terminal", since = "1.70.0")]
pub use self::stdio::IsTerminal;
#[unstable(feature = "print_internals", issue = "none")]
#[doc(hidden)]
pub use self::stdio::{_eprint, _print};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::{
2 changes: 2 additions & 0 deletions library/std/src/thread/mod.rs
Original file line number Diff line number Diff line change
@@ -546,6 +546,8 @@ impl Builder {
}

let main = Box::new(main);
// SAFETY: dynamic size and alignment of the Box remain the same. See below for why the
// lifetime change is justified.
#[cfg(bootstrap)]
let main =
unsafe { mem::transmute::<Box<dyn FnOnce() + 'a>, Box<dyn FnOnce() + 'static>>(main) };
2 changes: 1 addition & 1 deletion src/bootstrap/src/core/build_steps/test.rs
Original file line number Diff line number Diff line change
@@ -630,7 +630,7 @@ impl Step for Miri {
SourceType::InTree,
&[],
);
let _guard = builder.msg_sysroot_tool(Kind::Test, compiler.stage, "miri", host, host);
let _guard = builder.msg_sysroot_tool(Kind::Test, compiler.stage, "miri", host, target);

cargo.add_rustc_lib_path(builder, compiler);

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use std::collections::HashMap;
use std::hash::Hash;

trait LowT: Identify {}

trait Identify {
type Id: Clone + Hash + PartialEq + Eq;
fn identify(&self) -> Self::Id;
}

struct MapStore<L, I>
where
L: LowT + Identify<Id = I>,
{
lows: HashMap<I, L>,
}

impl<L, I> MapStore<L, I>
where
L: LowT + Identify<Id = I>,
I: Clone + Hash + PartialEq + Eq,
{
fn remove_low(&mut self, low: &impl LowT) {
let _low = self.lows.remove(low.identify()).unwrap(); //~ ERROR mismatched types
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
error[E0308]: mismatched types
--> $DIR/do-not-look-at-parent-item-in-suggestion-for-type-param-of-current-assoc-item.rs:24:37
|
LL | let _low = self.lows.remove(low.identify()).unwrap();
| ------ ^^^^^^^^^^^^^^ expected `&I`, found associated type
| |
| arguments to this method are incorrect
|
= note: expected reference `&I`
found associated type `<impl LowT as Identify>::Id`
= help: consider constraining the associated type `<impl LowT as Identify>::Id` to `&I`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
note: method defined here
--> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
7 changes: 7 additions & 0 deletions tests/ui/malformed/do-not-ice-on-note_and_explain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
struct A<B>(B);
impl<B>A<B>{fn d(){fn d(){Self(1)}}}
//~^ ERROR the size for values of type `B` cannot be known at compilation time
//~| ERROR the size for values of type `B` cannot be known at compilation time
//~| ERROR mismatched types
//~| ERROR mismatched types
//~| ERROR `main` function not found in crate
79 changes: 79 additions & 0 deletions tests/ui/malformed/do-not-ice-on-note_and_explain.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
error[E0601]: `main` function not found in crate `do_not_ice_on_note_and_explain`
--> $DIR/do-not-ice-on-note_and_explain.rs:2:37
|
LL | impl<B>A<B>{fn d(){fn d(){Self(1)}}}
| ^ consider adding a `main` function to `$DIR/do-not-ice-on-note_and_explain.rs`

error[E0277]: the size for values of type `B` cannot be known at compilation time
--> $DIR/do-not-ice-on-note_and_explain.rs:2:32
|
LL | impl<B>A<B>{fn d(){fn d(){Self(1)}}}
| - ---- ^ doesn't have a size known at compile-time
| | |
| | required by a bound introduced by this call
| this type parameter needs to be `Sized`
|
note: required by a bound in `A`
--> $DIR/do-not-ice-on-note_and_explain.rs:1:10
|
LL | struct A<B>(B);
| ^ required by this bound in `A`

error[E0308]: mismatched types
--> $DIR/do-not-ice-on-note_and_explain.rs:2:32
|
LL | impl<B>A<B>{fn d(){fn d(){Self(1)}}}
| ---- ^ expected type parameter `B`, found integer
| |
| arguments to this function are incorrect
|
= note: expected type parameter `B`
found type `{integer}`
note: tuple struct defined here
--> $DIR/do-not-ice-on-note_and_explain.rs:1:8
|
LL | struct A<B>(B);
| ^

error[E0308]: mismatched types
--> $DIR/do-not-ice-on-note_and_explain.rs:2:27
|
LL | impl<B>A<B>{fn d(){fn d(){Self(1)}}}
| ^^^^^^^ expected `()`, found `A<B>`
|
= note: expected unit type `()`
found struct `A<B>`
help: consider using a semicolon here
|
LL | impl<B>A<B>{fn d(){fn d(){Self(1);}}}
| +
help: try adding a return type
|
LL | impl<B>A<B>{fn d(){fn d() -> A<B>{Self(1)}}}
| +++++++

error[E0277]: the size for values of type `B` cannot be known at compilation time
--> $DIR/do-not-ice-on-note_and_explain.rs:2:27
|
LL | impl<B>A<B>{fn d(){fn d(){Self(1)}}}
| - ^^^^^^^ doesn't have a size known at compile-time
| |
| this type parameter needs to be `Sized`
|
note: required by a bound in `A`
--> $DIR/do-not-ice-on-note_and_explain.rs:1:10
|
LL | struct A<B>(B);
| ^ required by this bound in `A`
help: you could relax the implicit `Sized` bound on `B` if it were used through indirection like `&B` or `Box<B>`
--> $DIR/do-not-ice-on-note_and_explain.rs:1:10
|
LL | struct A<B>(B);
| ^ - ...if indirection were used here: `Box<B>`
| |
| this could be changed to `B: ?Sized`...

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0277, E0308, E0601.
For more information about an error, try `rustc --explain E0277`.
59 changes: 10 additions & 49 deletions tests/ui/parser/ternary_operator.rs
Original file line number Diff line number Diff line change
@@ -1,69 +1,30 @@
// A good chunk of these errors aren't shown to the user, but are still
// required in the test for it to pass.

fn a() { //~ NOTE this function should return `Result` or `Option` to accept `?`
fn a() {
let x = 5 > 2 ? true : false;
//~^ ERROR Rust has no ternary operator
//~| HELP use an `if-else` expression instead
//~| ERROR the `?` operator can only be applied to values that implement `Try` [E0277]
//~| HELP the trait `Try` is not implemented for `{integer}`
//~| ERROR the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) [E0277]
//~| HELP the trait `FromResidual<_>` is not implemented for `()`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE the `?` operator cannot be applied to type `{integer}`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE cannot use the `?` operator in a function that returns `()`
//~| NOTE in this expansion of desugaring of operator `?`
}

fn b() { //~ NOTE this function should return `Result` or `Option` to accept `?`
fn b() {
let x = 5 > 2 ? { true } : { false };
//~^ ERROR Rust has no ternary operator
//~| HELP use an `if-else` expression instead
//~| ERROR the `?` operator can only be applied to values that implement `Try` [E0277]
//~| HELP the trait `Try` is not implemented for `{integer}`
//~| ERROR the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) [E0277]
//~| HELP the trait `FromResidual<_>` is not implemented for `()`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE the `?` operator cannot be applied to type `{integer}`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE cannot use the `?` operator in a function that returns `()`
//~| NOTE in this expansion of desugaring of operator `?`
}

fn c() { //~ NOTE this function should return `Result` or `Option` to accept `?`
fn c() {
let x = 5 > 2 ? f32::MAX : f32::MIN;
//~^ ERROR Rust has no ternary operator
//~| HELP use an `if-else` expression instead
//~| ERROR the `?` operator can only be applied to values that implement `Try` [E0277]
//~| HELP the trait `Try` is not implemented for `{integer}`
//~| ERROR the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) [E0277]
//~| HELP the trait `FromResidual<_>` is not implemented for `()`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE the `?` operator cannot be applied to type `{integer}`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE cannot use the `?` operator in a function that returns `()`
//~| NOTE in this expansion of desugaring of operator `?`
}

fn main() { //~ NOTE this function should return `Result` or `Option` to accept `?`
fn bad() {
// regression test for #117208
v ? return;
//~^ ERROR expected one of
}

fn main() {
let x = 5 > 2 ? { let x = vec![]: Vec<u16>; x } : { false };
//~^ ERROR Rust has no ternary operator
//~| HELP use an `if-else` expression instead
//~| ERROR expected one of `.`, `;`, `?`, `else`, or an operator, found `:`
//~| NOTE expected one of `.`, `;`, `?`, `else`, or an operator
//~| ERROR the `?` operator can only be applied to values that implement `Try` [E0277]
//~| HELP the trait `Try` is not implemented for `{integer}`
//~| ERROR the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) [E0277]
//~| HELP the trait `FromResidual<_>` is not implemented for `()`
//~| NOTE type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE the `?` operator cannot be applied to type `{integer}`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE cannot use the `?` operator in a function that returns `()`
//~| NOTE in this expansion of desugaring of operator `?`
}
91 changes: 12 additions & 79 deletions tests/ui/parser/ternary_operator.stderr
Original file line number Diff line number Diff line change
@@ -1,115 +1,48 @@
error: Rust has no ternary operator
--> $DIR/ternary_operator.rs:5:19
--> $DIR/ternary_operator.rs:2:19
|
LL | let x = 5 > 2 ? true : false;
| ^^^^^^^^^^^^^^^
|
= help: use an `if-else` expression instead

error: Rust has no ternary operator
--> $DIR/ternary_operator.rs:21:19
--> $DIR/ternary_operator.rs:8:19
|
LL | let x = 5 > 2 ? { true } : { false };
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= help: use an `if-else` expression instead

error: Rust has no ternary operator
--> $DIR/ternary_operator.rs:37:19
--> $DIR/ternary_operator.rs:14:19
|
LL | let x = 5 > 2 ? f32::MAX : f32::MIN;
| ^^^^^^^^^^^^^^^^^^^^^^
|
= help: use an `if-else` expression instead

error: expected one of `.`, `;`, `?`, `}`, or an operator, found keyword `return`
--> $DIR/ternary_operator.rs:21:9
|
LL | v ? return;
| ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator

error: expected one of `.`, `;`, `?`, `else`, or an operator, found `:`
--> $DIR/ternary_operator.rs:53:37
--> $DIR/ternary_operator.rs:26:37
|
LL | let x = 5 > 2 ? { let x = vec![]: Vec<u16>; x } : { false };
| ^ expected one of `.`, `;`, `?`, `else`, or an operator
|
= note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>

error: Rust has no ternary operator
--> $DIR/ternary_operator.rs:53:19
--> $DIR/ternary_operator.rs:26:19
|
LL | let x = 5 > 2 ? { let x = vec![]: Vec<u16>; x } : { false };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: use an `if-else` expression instead

error[E0277]: the `?` operator can only be applied to values that implement `Try`
--> $DIR/ternary_operator.rs:5:17
|
LL | let x = 5 > 2 ? true : false;
| ^^^ the `?` operator cannot be applied to type `{integer}`
|
= help: the trait `Try` is not implemented for `{integer}`

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/ternary_operator.rs:5:19
|
LL | fn a() {
| ------ this function should return `Result` or `Option` to accept `?`
LL | let x = 5 > 2 ? true : false;
| ^ cannot use the `?` operator in a function that returns `()`
|
= help: the trait `FromResidual<_>` is not implemented for `()`

error[E0277]: the `?` operator can only be applied to values that implement `Try`
--> $DIR/ternary_operator.rs:21:17
|
LL | let x = 5 > 2 ? { true } : { false };
| ^^^ the `?` operator cannot be applied to type `{integer}`
|
= help: the trait `Try` is not implemented for `{integer}`

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/ternary_operator.rs:21:19
|
LL | fn b() {
| ------ this function should return `Result` or `Option` to accept `?`
LL | let x = 5 > 2 ? { true } : { false };
| ^ cannot use the `?` operator in a function that returns `()`
|
= help: the trait `FromResidual<_>` is not implemented for `()`

error[E0277]: the `?` operator can only be applied to values that implement `Try`
--> $DIR/ternary_operator.rs:37:17
|
LL | let x = 5 > 2 ? f32::MAX : f32::MIN;
| ^^^ the `?` operator cannot be applied to type `{integer}`
|
= help: the trait `Try` is not implemented for `{integer}`

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/ternary_operator.rs:37:19
|
LL | fn c() {
| ------ this function should return `Result` or `Option` to accept `?`
LL | let x = 5 > 2 ? f32::MAX : f32::MIN;
| ^ cannot use the `?` operator in a function that returns `()`
|
= help: the trait `FromResidual<_>` is not implemented for `()`

error[E0277]: the `?` operator can only be applied to values that implement `Try`
--> $DIR/ternary_operator.rs:53:17
|
LL | let x = 5 > 2 ? { let x = vec![]: Vec<u16>; x } : { false };
| ^^^ the `?` operator cannot be applied to type `{integer}`
|
= help: the trait `Try` is not implemented for `{integer}`

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/ternary_operator.rs:53:19
|
LL | fn main() {
| --------- this function should return `Result` or `Option` to accept `?`
LL | let x = 5 > 2 ? { let x = vec![]: Vec<u16>; x } : { false };
| ^ cannot use the `?` operator in a function that returns `()`
|
= help: the trait `FromResidual<_>` is not implemented for `()`

error: aborting due to 13 previous errors
error: aborting due to 6 previous errors

For more information about this error, try `rustc --explain E0277`.