Auto merge of #99177 - Dylan-DPC:rollup-m0k9q2w, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #98622 (rustc_target: Flip the default for `TargetOptions::executables` to true) - #98633 (Fix last `let_chains` blocker) - #98972 (Suggest adding a missing zero to a floating point number) - #99038 (Some more `EarlyBinder` cleanups) - #99154 (use PlaceRef::iter_projections to fix old FIXME) - #99171 (Put back UI test regex) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
1c7b36d4db
82 changed files with 1180 additions and 427 deletions
|
@ -1111,11 +1111,9 @@ macro_rules! visit_place_fns {
|
|||
context: PlaceContext,
|
||||
location: Location,
|
||||
) {
|
||||
// FIXME: Use PlaceRef::iter_projections, once that exists.
|
||||
let mut cursor = place_ref.projection;
|
||||
while let &[ref proj_base @ .., elem] = cursor {
|
||||
cursor = proj_base;
|
||||
self.visit_projection_elem(place_ref.local, cursor, elem, context, location);
|
||||
for (base, elem) in place_ref.iter_projections().rev() {
|
||||
let base_proj = base.projection;
|
||||
self.visit_projection_elem(place_ref.local, base_proj, elem, context, location);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,10 +85,10 @@ impl GenericParamDef {
|
|||
) -> Option<EarlyBinder<ty::GenericArg<'tcx>>> {
|
||||
match self.kind {
|
||||
GenericParamDefKind::Type { has_default, .. } if has_default => {
|
||||
Some(EarlyBinder(tcx.type_of(self.def_id).into()))
|
||||
Some(tcx.bound_type_of(self.def_id).map_bound(|t| t.into()))
|
||||
}
|
||||
GenericParamDefKind::Const { has_default } if has_default => {
|
||||
Some(EarlyBinder(tcx.const_param_default(self.def_id).into()))
|
||||
Some(tcx.bound_const_param_default(self.def_id).map_bound(|c| c.into()))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
|
|
@ -932,6 +932,10 @@ impl<T> EarlyBinder<T> {
|
|||
let value = f(self.0)?;
|
||||
Ok(EarlyBinder(value))
|
||||
}
|
||||
|
||||
pub fn rebind<U>(&self, value: U) -> EarlyBinder<U> {
|
||||
EarlyBinder(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> EarlyBinder<Option<T>> {
|
||||
|
|
|
@ -676,6 +676,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
) -> ty::EarlyBinder<&'tcx ty::List<ty::Predicate<'tcx>>> {
|
||||
ty::EarlyBinder(self.item_bounds(def_id))
|
||||
}
|
||||
|
||||
pub fn bound_const_param_default(self, def_id: DefId) -> ty::EarlyBinder<ty::Const<'tcx>> {
|
||||
ty::EarlyBinder(self.const_param_default(def_id))
|
||||
}
|
||||
}
|
||||
|
||||
struct OpaqueTypeExpander<'tcx> {
|
||||
|
|
|
@ -537,13 +537,12 @@ fn build_call_shim<'tcx>(
|
|||
};
|
||||
|
||||
let def_id = instance.def_id();
|
||||
let sig = tcx.fn_sig(def_id);
|
||||
let mut sig = tcx.erase_late_bound_regions(sig);
|
||||
let sig = tcx.bound_fn_sig(def_id);
|
||||
let sig = sig.map_bound(|sig| tcx.erase_late_bound_regions(sig));
|
||||
|
||||
assert_eq!(sig_substs.is_some(), !instance.has_polymorphic_mir_body());
|
||||
if let Some(sig_substs) = sig_substs {
|
||||
sig = EarlyBinder(sig).subst(tcx, sig_substs);
|
||||
}
|
||||
let mut sig =
|
||||
if let Some(sig_substs) = sig_substs { sig.subst(tcx, sig_substs) } else { sig.0 };
|
||||
|
||||
if let CallKind::Indirect(fnty) = call_kind {
|
||||
// `sig` determines our local decls, and thus the callee type in the `Call` terminator. This
|
||||
|
|
|
@ -1393,7 +1393,9 @@ impl<'a> Parser<'a> {
|
|||
self.parse_yield_expr(attrs)
|
||||
} else if self.is_do_yeet() {
|
||||
self.parse_yeet_expr(attrs)
|
||||
} else if self.eat_keyword(kw::Let) {
|
||||
} else if self.check_keyword(kw::Let) {
|
||||
self.manage_let_chains_context();
|
||||
self.bump();
|
||||
self.parse_let_expr(attrs)
|
||||
} else if self.eat_keyword(kw::Underscore) {
|
||||
Ok(self.mk_expr(self.prev_token.span, ExprKind::Underscore, attrs))
|
||||
|
@ -2355,16 +2357,30 @@ impl<'a> Parser<'a> {
|
|||
Ok(cond)
|
||||
}
|
||||
|
||||
// Checks if `let` is in an invalid position like `let x = let y = 1;` or
|
||||
// if the current `let` is in a let_chains context but nested in another
|
||||
// expression like `if let Some(_) = _opt && [1, 2, 3][let _ = ()] = 1`.
|
||||
//
|
||||
// This method expects that the current token is `let`.
|
||||
fn manage_let_chains_context(&mut self) {
|
||||
debug_assert!(matches!(self.token.kind, TokenKind::Ident(kw::Let, _)));
|
||||
let is_in_a_let_chains_context_but_nested_in_other_expr = self.let_expr_allowed
|
||||
&& !matches!(
|
||||
self.prev_token.kind,
|
||||
TokenKind::AndAnd
|
||||
| TokenKind::CloseDelim(Delimiter::Brace)
|
||||
| TokenKind::Ident(kw::If, _)
|
||||
| TokenKind::Ident(kw::While, _)
|
||||
);
|
||||
if !self.let_expr_allowed || is_in_a_let_chains_context_but_nested_in_other_expr {
|
||||
self.struct_span_err(self.token.span, "expected expression, found `let` statement")
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses a `let $pat = $expr` pseudo-expression.
|
||||
/// The `let` token has already been eaten.
|
||||
fn parse_let_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
|
||||
if !self.let_expr_allowed {
|
||||
self.struct_span_err(
|
||||
self.prev_token.span,
|
||||
"expected expression, found `let` statement",
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
let lo = self.prev_token.span;
|
||||
let pat = self.parse_pat_allow_top_alt(
|
||||
None,
|
||||
|
|
|
@ -13,7 +13,6 @@ pub fn target() -> Target {
|
|||
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
linker: Some("rust-lld".into()),
|
||||
features: "+strict-align,+neon,+fp-armv8".into(),
|
||||
executables: true,
|
||||
relocation_model: RelocModel::Static,
|
||||
disable_redzone: true,
|
||||
max_atomic_width: Some(128),
|
||||
|
|
|
@ -14,7 +14,6 @@ pub fn target() -> Target {
|
|||
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
linker: Some("rust-lld".into()),
|
||||
features: "+strict-align,-neon,-fp-armv8".into(),
|
||||
executables: true,
|
||||
relocation_model: RelocModel::Static,
|
||||
disable_redzone: true,
|
||||
max_atomic_width: Some(128),
|
||||
|
|
|
@ -25,7 +25,6 @@ pub fn opts(os: &'static str) -> TargetOptions {
|
|||
function_sections: false,
|
||||
dynamic_linking: true,
|
||||
linker_is_gnu: false,
|
||||
executables: true,
|
||||
families: cvs!["unix"],
|
||||
is_like_osx: true,
|
||||
default_dwarf_version: 2,
|
||||
|
|
|
@ -54,7 +54,6 @@ pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
|
|||
abi: target_abi(arch).into(),
|
||||
cpu: target_cpu(arch).into(),
|
||||
dynamic_linking: false,
|
||||
executables: true,
|
||||
link_env_remove: link_env_remove(arch),
|
||||
has_thread_local: false,
|
||||
..super::apple_base::opts(os)
|
||||
|
|
|
@ -14,7 +14,6 @@ pub fn target() -> Target {
|
|||
abi: "eabi".into(),
|
||||
endian: Endian::Big,
|
||||
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
executables: true,
|
||||
linker: Some("rust-lld".into()),
|
||||
relocation_model: RelocModel::Static,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
|
|
|
@ -14,7 +14,6 @@ pub fn target() -> Target {
|
|||
abi: "eabihf".into(),
|
||||
endian: Endian::Big,
|
||||
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
executables: true,
|
||||
linker: Some("rust-lld".into()),
|
||||
relocation_model: RelocModel::Static,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
|
|
|
@ -23,7 +23,6 @@ pub fn target() -> Target {
|
|||
abi: "eabihf".into(),
|
||||
linker_flavor: LinkerFlavor::Gcc,
|
||||
cpu: "mpcore".into(),
|
||||
executables: true,
|
||||
families: cvs!["unix"],
|
||||
linker: Some("arm-none-eabi-gcc".into()),
|
||||
relocation_model: RelocModel::Static,
|
||||
|
|
|
@ -22,7 +22,6 @@ pub fn target() -> Target {
|
|||
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
linker: Some("rust-lld".into()),
|
||||
features: "+v7,+thumb2,+soft-float,-neon,+strict-align".into(),
|
||||
executables: true,
|
||||
relocation_model: RelocModel::Static,
|
||||
disable_redzone: true,
|
||||
max_atomic_width: Some(64),
|
||||
|
|
|
@ -13,7 +13,6 @@ pub fn target() -> Target {
|
|||
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
linker: Some("rust-lld".into()),
|
||||
features: "+v7,+vfp3,-d32,+thumb2,-neon,+strict-align".into(),
|
||||
executables: true,
|
||||
relocation_model: RelocModel::Static,
|
||||
disable_redzone: true,
|
||||
max_atomic_width: Some(64),
|
||||
|
|
|
@ -13,7 +13,6 @@ pub fn target() -> Target {
|
|||
options: TargetOptions {
|
||||
abi: "eabi".into(),
|
||||
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
executables: true,
|
||||
linker: Some("rust-lld".into()),
|
||||
relocation_model: RelocModel::Static,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
|
|
|
@ -13,7 +13,6 @@ pub fn target() -> Target {
|
|||
options: TargetOptions {
|
||||
abi: "eabihf".into(),
|
||||
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
executables: true,
|
||||
linker: Some("rust-lld".into()),
|
||||
relocation_model: RelocModel::Static,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
|
|
|
@ -16,7 +16,6 @@ pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
|
|||
exe_suffix: ".elf".into(),
|
||||
|
||||
linker: Some("avr-gcc".into()),
|
||||
executables: true,
|
||||
eh_frame_header: false,
|
||||
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gcc, &[mmcu]),
|
||||
late_link_args: TargetOptions::link_args(LinkerFlavor::Gcc, &["-lgcc"]),
|
||||
|
|
|
@ -7,7 +7,6 @@ pub fn opts(endian: Endian) -> TargetOptions {
|
|||
endian,
|
||||
linker_flavor: LinkerFlavor::BpfLinker,
|
||||
atomic_cas: false,
|
||||
executables: true,
|
||||
dynamic_linking: true,
|
||||
no_builtins: true,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
|
|
|
@ -4,7 +4,6 @@ pub fn opts() -> TargetOptions {
|
|||
TargetOptions {
|
||||
os: "dragonfly".into(),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
families: cvs!["unix"],
|
||||
has_rpath: true,
|
||||
position_independent_executables: true,
|
||||
|
|
|
@ -4,7 +4,6 @@ pub fn opts() -> TargetOptions {
|
|||
TargetOptions {
|
||||
os: "freebsd".into(),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
families: cvs!["unix"],
|
||||
has_rpath: true,
|
||||
position_independent_executables: true,
|
||||
|
|
|
@ -23,7 +23,6 @@ pub fn opts() -> TargetOptions {
|
|||
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
linker: Some("rust-lld".into()),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
families: cvs!["unix"],
|
||||
pre_link_args,
|
||||
pre_link_objects: crt_objects::new(&[
|
||||
|
|
|
@ -4,7 +4,6 @@ pub fn opts() -> TargetOptions {
|
|||
TargetOptions {
|
||||
os: "haiku".into(),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
families: cvs!["unix"],
|
||||
relro_level: RelroLevel::Full,
|
||||
..Default::default()
|
||||
|
|
|
@ -10,7 +10,6 @@ pub fn opts() -> TargetOptions {
|
|||
os: "hermit".into(),
|
||||
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
linker: Some("rust-lld".into()),
|
||||
executables: true,
|
||||
has_thread_local: true,
|
||||
pre_link_args,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
|
|
|
@ -11,7 +11,6 @@ pub fn target() -> Target {
|
|||
base.has_rpath = true;
|
||||
base.linker_is_gnu = false;
|
||||
base.dynamic_linking = true;
|
||||
base.executables = true;
|
||||
|
||||
base.c_enum_min_bits = 8;
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ pub fn opts() -> TargetOptions {
|
|||
TargetOptions {
|
||||
os: "illumos".into(),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
has_rpath: true,
|
||||
families: cvs!["unix"],
|
||||
is_like_solaris: true,
|
||||
|
|
|
@ -5,7 +5,6 @@ pub fn opts() -> TargetOptions {
|
|||
os: "l4re".into(),
|
||||
env: "uclibc".into(),
|
||||
linker_flavor: LinkerFlavor::L4Bender,
|
||||
executables: true,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
linker: Some("l4-bender".into()),
|
||||
linker_is_gnu: false,
|
||||
|
|
|
@ -4,7 +4,6 @@ pub fn opts() -> TargetOptions {
|
|||
TargetOptions {
|
||||
os: "linux".into(),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
families: cvs!["unix"],
|
||||
has_rpath: true,
|
||||
position_independent_executables: true,
|
||||
|
|
|
@ -18,7 +18,6 @@ pub fn target() -> Target {
|
|||
vendor: "sony".into(),
|
||||
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
cpu: "mips2".into(),
|
||||
executables: true,
|
||||
linker: Some("rust-lld".into()),
|
||||
relocation_model: RelocModel::Static,
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ pub fn target() -> Target {
|
|||
cpu: "mips32r2".into(),
|
||||
features: "+mips32r2,+soft-float,+noabicalls".into(),
|
||||
max_atomic_width: Some(32),
|
||||
executables: true,
|
||||
linker: Some("rust-lld".into()),
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
relocation_model: RelocModel::Static,
|
||||
|
|
|
@ -1212,8 +1212,7 @@ pub struct TargetOptions {
|
|||
pub dynamic_linking: bool,
|
||||
/// If dynamic linking is available, whether only cdylibs are supported.
|
||||
pub only_cdylib: bool,
|
||||
/// Whether executables are available on this target. iOS, for example, only allows static
|
||||
/// libraries. Defaults to false.
|
||||
/// Whether executables are available on this target. Defaults to true.
|
||||
pub executables: bool,
|
||||
/// Relocation model to use in object file. Corresponds to `llc
|
||||
/// -relocation-model=$relocation_model`. Defaults to `Pic`.
|
||||
|
@ -1520,7 +1519,7 @@ impl Default for TargetOptions {
|
|||
features: "".into(),
|
||||
dynamic_linking: false,
|
||||
only_cdylib: false,
|
||||
executables: false,
|
||||
executables: true,
|
||||
relocation_model: RelocModel::Pic,
|
||||
code_model: None,
|
||||
tls_model: TlsModel::GeneralDynamic,
|
||||
|
|
|
@ -9,7 +9,6 @@ pub fn target() -> Target {
|
|||
|
||||
options: TargetOptions {
|
||||
c_int_width: "16".into(),
|
||||
executables: true,
|
||||
|
||||
// The LLVM backend currently can't generate object files. To
|
||||
// workaround this LLVM generates assembly files which then we feed
|
||||
|
|
|
@ -7,7 +7,6 @@ pub fn opts() -> TargetOptions {
|
|||
|
||||
TargetOptions {
|
||||
linker_flavor: LinkerFlavor::Msvc,
|
||||
executables: true,
|
||||
is_like_windows: true,
|
||||
is_like_msvc: true,
|
||||
lld_flavor: LldFlavor::Link,
|
||||
|
|
|
@ -4,7 +4,6 @@ pub fn opts() -> TargetOptions {
|
|||
TargetOptions {
|
||||
os: "netbsd".into(),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
families: cvs!["unix"],
|
||||
no_default_libraries: false,
|
||||
has_rpath: true,
|
||||
|
|
|
@ -26,7 +26,6 @@ pub fn target() -> Target {
|
|||
|
||||
// Needed to use `dylib` and `bin` crate types and the linker.
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
|
||||
// Avoid using dylib because it contain metadata not supported
|
||||
// by LLVM NVPTX backend.
|
||||
|
|
|
@ -4,7 +4,6 @@ pub fn opts() -> TargetOptions {
|
|||
TargetOptions {
|
||||
os: "openbsd".into(),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
families: cvs!["unix"],
|
||||
has_rpath: true,
|
||||
abi_return_struct_as_int: true,
|
||||
|
|
|
@ -5,7 +5,6 @@ pub fn opts() -> TargetOptions {
|
|||
os: "redox".into(),
|
||||
env: "relibc".into(),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
families: cvs!["unix"],
|
||||
has_rpath: true,
|
||||
position_independent_executables: true,
|
||||
|
|
|
@ -14,7 +14,6 @@ pub fn target() -> Target {
|
|||
cpu: "generic-rv32".into(),
|
||||
max_atomic_width: Some(0),
|
||||
atomic_cas: false,
|
||||
executables: true,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
relocation_model: RelocModel::Static,
|
||||
emit_debug_gdb_scripts: false,
|
||||
|
|
|
@ -15,7 +15,6 @@ pub fn target() -> Target {
|
|||
max_atomic_width: Some(0),
|
||||
atomic_cas: false,
|
||||
features: "+m".into(),
|
||||
executables: true,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
relocation_model: RelocModel::Static,
|
||||
emit_debug_gdb_scripts: false,
|
||||
|
|
|
@ -14,7 +14,6 @@ pub fn target() -> Target {
|
|||
cpu: "generic-rv32".into(),
|
||||
max_atomic_width: Some(32),
|
||||
features: "+m,+a,+c".into(),
|
||||
executables: true,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
relocation_model: RelocModel::Static,
|
||||
emit_debug_gdb_scripts: false,
|
||||
|
|
|
@ -15,7 +15,6 @@ pub fn target() -> Target {
|
|||
cpu: "generic-rv32".into(),
|
||||
max_atomic_width: Some(32),
|
||||
features: "+m,+a,+c".into(),
|
||||
executables: true,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
relocation_model: RelocModel::Static,
|
||||
..Default::default()
|
||||
|
|
|
@ -26,7 +26,6 @@ pub fn target() -> Target {
|
|||
atomic_cas: true,
|
||||
|
||||
features: "+m,+c".into(),
|
||||
executables: true,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
relocation_model: RelocModel::Static,
|
||||
emit_debug_gdb_scripts: false,
|
||||
|
|
|
@ -15,7 +15,6 @@ pub fn target() -> Target {
|
|||
max_atomic_width: Some(0),
|
||||
atomic_cas: false,
|
||||
features: "+m,+c".into(),
|
||||
executables: true,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
relocation_model: RelocModel::Static,
|
||||
emit_debug_gdb_scripts: false,
|
||||
|
|
|
@ -15,7 +15,6 @@ pub fn target() -> Target {
|
|||
cpu: "generic-rv64".into(),
|
||||
max_atomic_width: Some(64),
|
||||
features: "+m,+a,+f,+d,+c".into(),
|
||||
executables: true,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
relocation_model: RelocModel::Static,
|
||||
code_model: Some(CodeModel::Medium),
|
||||
|
|
|
@ -14,7 +14,6 @@ pub fn target() -> Target {
|
|||
cpu: "generic-rv64".into(),
|
||||
max_atomic_width: Some(64),
|
||||
features: "+m,+a,+c".into(),
|
||||
executables: true,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
relocation_model: RelocModel::Static,
|
||||
code_model: Some(CodeModel::Medium),
|
||||
|
|
|
@ -4,7 +4,6 @@ pub fn opts() -> TargetOptions {
|
|||
TargetOptions {
|
||||
os: "solaris".into(),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
has_rpath: true,
|
||||
families: cvs!["unix"],
|
||||
is_like_solaris: true,
|
||||
|
|
|
@ -5,6 +5,7 @@ pub fn opts(kernel: &str) -> TargetOptions {
|
|||
TargetOptions {
|
||||
os: format!("solid_{}", kernel).into(),
|
||||
vendor: "kmc".into(),
|
||||
executables: false,
|
||||
frame_pointer: FramePointer::NonLeaf,
|
||||
has_thread_local: true,
|
||||
..Default::default()
|
||||
|
|
|
@ -34,7 +34,6 @@ pub fn opts() -> TargetOptions {
|
|||
// See rust-lang/rfcs#1645 for a discussion about these defaults
|
||||
TargetOptions {
|
||||
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
executables: true,
|
||||
// In most cases, LLD is good enough
|
||||
linker: Some("rust-lld".into()),
|
||||
// Because these devices have very little resources having an unwinder is too onerous so we
|
||||
|
|
|
@ -8,7 +8,6 @@ pub fn opts() -> TargetOptions {
|
|||
linker: Some("wr-c++".into()),
|
||||
exe_suffix: ".vxe".into(),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
families: cvs!["unix"],
|
||||
has_rpath: true,
|
||||
has_thread_local: true,
|
||||
|
|
|
@ -62,9 +62,6 @@ pub fn options() -> TargetOptions {
|
|||
dynamic_linking: true,
|
||||
only_cdylib: true,
|
||||
|
||||
// This means we'll just embed a `#[start]` function in the wasm module
|
||||
executables: true,
|
||||
|
||||
// relatively self-explanatory!
|
||||
exe_suffix: ".wasm".into(),
|
||||
dll_prefix: "".into(),
|
||||
|
|
|
@ -67,7 +67,6 @@ pub fn opts() -> TargetOptions {
|
|||
function_sections: false,
|
||||
linker: Some("gcc".into()),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
dll_prefix: "".into(),
|
||||
dll_suffix: ".dll".into(),
|
||||
exe_suffix: ".exe".into(),
|
||||
|
|
|
@ -20,7 +20,6 @@ pub fn opts() -> TargetOptions {
|
|||
abi: "llvm".into(),
|
||||
linker: Some("clang".into()),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
dll_prefix: "".into(),
|
||||
dll_suffix: ".dll".into(),
|
||||
exe_suffix: ".exe".into(),
|
||||
|
|
|
@ -24,7 +24,6 @@ pub fn opts() -> TargetOptions {
|
|||
TargetOptions {
|
||||
abi: "uwp".into(),
|
||||
vendor: "uwp".into(),
|
||||
executables: false,
|
||||
limit_rdylib_exports: false,
|
||||
late_link_args,
|
||||
late_link_args_dynamic,
|
||||
|
|
|
@ -62,7 +62,6 @@ pub fn target() -> Target {
|
|||
vendor: "fortanix".into(),
|
||||
abi: "fortanix".into(),
|
||||
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
executables: true,
|
||||
linker: Some("rust-lld".into()),
|
||||
max_atomic_width: Some(64),
|
||||
cpu: "x86-64".into(),
|
||||
|
|
|
@ -24,7 +24,6 @@ pub fn target() -> Target {
|
|||
features:
|
||||
"-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float"
|
||||
.into(),
|
||||
executables: true,
|
||||
disable_redzone: true,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
code_model: Some(CodeModel::Kernel),
|
||||
|
|
|
@ -12,7 +12,7 @@ use rustc_index::bit_set::GrowableBitSet;
|
|||
use rustc_infer::infer::InferOk;
|
||||
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef};
|
||||
use rustc_middle::ty::{self, EarlyBinder, GenericParamDefKind, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, GenericParamDefKind, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{ToPolyTraitRef, ToPredicate};
|
||||
use rustc_span::def_id::DefId;
|
||||
|
||||
|
@ -555,7 +555,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
|
||||
let bound =
|
||||
EarlyBinder(bound.0.kind().skip_binder()).subst(tcx, assoc_ty_substs);
|
||||
bound.map_bound(|b| b.kind().skip_binder()).subst(tcx, assoc_ty_substs);
|
||||
tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars))
|
||||
};
|
||||
let normalized_bound = normalize_with_depth_to(
|
||||
|
|
|
@ -550,7 +550,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
GenericParamDefKind::Const { has_default } => {
|
||||
let ty = tcx.at(self.span).type_of(param.def_id);
|
||||
if !infer_args && has_default {
|
||||
EarlyBinder(tcx.const_param_default(param.def_id))
|
||||
tcx.bound_const_param_default(param.def_id)
|
||||
.subst(tcx, substs.unwrap())
|
||||
.into()
|
||||
} else {
|
||||
|
|
|
@ -48,7 +48,7 @@ use rustc_middle::ty::{self, AdtKind, DefIdTree, Ty, TypeVisitable};
|
|||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::hygiene::DesugaringKind;
|
||||
use rustc_span::lev_distance::find_best_match_for_name;
|
||||
use rustc_span::source_map::Span;
|
||||
use rustc_span::source_map::{Span, Spanned};
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{BytePos, Pos};
|
||||
use rustc_target::spec::abi::Abi::RustIntrinsic;
|
||||
|
@ -2162,14 +2162,55 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
} else if !expr_t.is_primitive_ty() {
|
||||
self.ban_nonexisting_field(field, base, expr, expr_t);
|
||||
} else {
|
||||
type_error_struct!(
|
||||
let field_name = field.to_string();
|
||||
let mut err = type_error_struct!(
|
||||
self.tcx().sess,
|
||||
field.span,
|
||||
expr_t,
|
||||
E0610,
|
||||
"`{expr_t}` is a primitive type and therefore doesn't have fields",
|
||||
)
|
||||
.emit();
|
||||
);
|
||||
let is_valid_suffix = |field: String| {
|
||||
if field == "f32" || field == "f64" {
|
||||
return true;
|
||||
}
|
||||
let mut chars = field.chars().peekable();
|
||||
match chars.peek() {
|
||||
Some('e') | Some('E') => {
|
||||
chars.next();
|
||||
if let Some(c) = chars.peek()
|
||||
&& !c.is_numeric() && *c != '-' && *c != '+'
|
||||
{
|
||||
return false;
|
||||
}
|
||||
while let Some(c) = chars.peek() {
|
||||
if !c.is_numeric() {
|
||||
break;
|
||||
}
|
||||
chars.next();
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
let suffix = chars.collect::<String>();
|
||||
suffix.is_empty() || suffix == "f32" || suffix == "f64"
|
||||
};
|
||||
if let ty::Infer(ty::IntVar(_)) = expr_t.kind()
|
||||
&& let ExprKind::Lit(Spanned {
|
||||
node: ast::LitKind::Int(_, ast::LitIntType::Unsuffixed),
|
||||
..
|
||||
}) = base.kind
|
||||
&& !base.span.from_expansion()
|
||||
&& is_valid_suffix(field_name)
|
||||
{
|
||||
err.span_suggestion_verbose(
|
||||
field.span.shrink_to_lo(),
|
||||
"If the number is meant to be a floating point number, consider adding a `0` after the period",
|
||||
'0',
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
|
||||
self.tcx().ty_error()
|
||||
|
|
|
@ -1426,7 +1426,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
GenericParamDefKind::Const { has_default } => {
|
||||
if !infer_args && has_default {
|
||||
EarlyBinder(tcx.const_param_default(param.def_id))
|
||||
tcx.bound_const_param_default(param.def_id)
|
||||
.subst(tcx, substs.unwrap())
|
||||
.into()
|
||||
} else {
|
||||
|
|
|
@ -21,9 +21,7 @@ use rustc_middle::middle::stability;
|
|||
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
|
||||
use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
|
||||
use rustc_middle::ty::GenericParamDefKind;
|
||||
use rustc_middle::ty::{
|
||||
self, EarlyBinder, ParamEnvAnd, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitable,
|
||||
};
|
||||
use rustc_middle::ty::{self, ParamEnvAnd, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitable};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::lev_distance::{
|
||||
|
@ -713,7 +711,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
let (impl_ty, impl_substs) = self.impl_ty_and_substs(impl_def_id);
|
||||
let impl_ty = EarlyBinder(impl_ty).subst(self.tcx, impl_substs);
|
||||
let impl_ty = impl_ty.subst(self.tcx, impl_substs);
|
||||
|
||||
debug!("impl_ty: {:?}", impl_ty);
|
||||
|
||||
|
@ -1811,9 +1809,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
self.erase_late_bound_regions(xform_fn_sig)
|
||||
}
|
||||
|
||||
/// Gets the type of an impl and generate substitutions with placeholders.
|
||||
fn impl_ty_and_substs(&self, impl_def_id: DefId) -> (Ty<'tcx>, SubstsRef<'tcx>) {
|
||||
(self.tcx.type_of(impl_def_id), self.fresh_item_substs(impl_def_id))
|
||||
/// Gets the type of an impl and generate substitutions with inference vars.
|
||||
fn impl_ty_and_substs(
|
||||
&self,
|
||||
impl_def_id: DefId,
|
||||
) -> (ty::EarlyBinder<Ty<'tcx>>, SubstsRef<'tcx>) {
|
||||
(self.tcx.bound_type_of(impl_def_id), self.fresh_item_substs(impl_def_id))
|
||||
}
|
||||
|
||||
fn fresh_item_substs(&self, def_id: DefId) -> SubstsRef<'tcx> {
|
||||
|
|
|
@ -6,7 +6,7 @@ use super::utils::*;
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct ExplicitPredicatesMap<'tcx> {
|
||||
map: FxHashMap<DefId, RequiredPredicates<'tcx>>,
|
||||
map: FxHashMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
|
||||
}
|
||||
|
||||
impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
||||
|
@ -14,11 +14,11 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
|||
ExplicitPredicatesMap { map: FxHashMap::default() }
|
||||
}
|
||||
|
||||
pub fn explicit_predicates_of(
|
||||
pub(crate) fn explicit_predicates_of(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
) -> &RequiredPredicates<'tcx> {
|
||||
) -> &ty::EarlyBinder<RequiredPredicates<'tcx>> {
|
||||
self.map.entry(def_id).or_insert_with(|| {
|
||||
let predicates = if def_id.is_local() {
|
||||
tcx.explicit_predicates_of(def_id)
|
||||
|
@ -63,7 +63,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
required_predicates
|
||||
ty::EarlyBinder(required_predicates)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use rustc_data_structures::fx::FxHashMap;
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
|
||||
use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_span::Span;
|
||||
|
||||
use super::explicit::ExplicitPredicatesMap;
|
||||
|
@ -13,20 +13,19 @@ use super::utils::*;
|
|||
/// `global_inferred_outlives`: this is initially the empty map that
|
||||
/// was generated by walking the items in the crate. This will
|
||||
/// now be filled with inferred predicates.
|
||||
pub fn infer_predicates<'tcx>(
|
||||
pub(super) fn infer_predicates<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
explicit_map: &mut ExplicitPredicatesMap<'tcx>,
|
||||
) -> FxHashMap<DefId, RequiredPredicates<'tcx>> {
|
||||
) -> FxHashMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>> {
|
||||
debug!("infer_predicates");
|
||||
|
||||
let mut predicates_added = true;
|
||||
let mut explicit_map = ExplicitPredicatesMap::new();
|
||||
|
||||
let mut global_inferred_outlives = FxHashMap::default();
|
||||
|
||||
// If new predicates were added then we need to re-calculate
|
||||
// all crates since there could be new implied predicates.
|
||||
while predicates_added {
|
||||
predicates_added = false;
|
||||
'outer: loop {
|
||||
let mut predicates_added = false;
|
||||
|
||||
// Visit all the crates and infer predicates
|
||||
for id in tcx.hir().items() {
|
||||
|
@ -53,9 +52,9 @@ pub fn infer_predicates<'tcx>(
|
|||
tcx,
|
||||
field_ty,
|
||||
field_span,
|
||||
&mut global_inferred_outlives,
|
||||
&global_inferred_outlives,
|
||||
&mut item_required_predicates,
|
||||
explicit_map,
|
||||
&mut explicit_map,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -70,12 +69,17 @@ pub fn infer_predicates<'tcx>(
|
|||
// we walk the crates again and re-calculate predicates for all
|
||||
// items.
|
||||
let item_predicates_len: usize =
|
||||
global_inferred_outlives.get(&item_did.to_def_id()).map_or(0, |p| p.len());
|
||||
global_inferred_outlives.get(&item_did.to_def_id()).map_or(0, |p| p.0.len());
|
||||
if item_required_predicates.len() > item_predicates_len {
|
||||
predicates_added = true;
|
||||
global_inferred_outlives.insert(item_did.to_def_id(), item_required_predicates);
|
||||
global_inferred_outlives
|
||||
.insert(item_did.to_def_id(), ty::EarlyBinder(item_required_predicates));
|
||||
}
|
||||
}
|
||||
|
||||
if !predicates_added {
|
||||
break 'outer;
|
||||
}
|
||||
}
|
||||
|
||||
global_inferred_outlives
|
||||
|
@ -85,7 +89,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
field_ty: Ty<'tcx>,
|
||||
field_span: Span,
|
||||
global_inferred_outlives: &FxHashMap<DefId, RequiredPredicates<'tcx>>,
|
||||
global_inferred_outlives: &FxHashMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
|
||||
required_predicates: &mut RequiredPredicates<'tcx>,
|
||||
explicit_map: &mut ExplicitPredicatesMap<'tcx>,
|
||||
) {
|
||||
|
@ -133,11 +137,13 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
|||
// 'a` holds for `Foo`.
|
||||
debug!("Adt");
|
||||
if let Some(unsubstituted_predicates) = global_inferred_outlives.get(&def.did()) {
|
||||
for (unsubstituted_predicate, &span) in unsubstituted_predicates {
|
||||
for (unsubstituted_predicate, &span) in &unsubstituted_predicates.0 {
|
||||
// `unsubstituted_predicate` is `U: 'b` in the
|
||||
// example above. So apply the substitution to
|
||||
// get `T: 'a` (or `predicate`):
|
||||
let predicate = EarlyBinder(*unsubstituted_predicate).subst(tcx, substs);
|
||||
let predicate = unsubstituted_predicates
|
||||
.rebind(*unsubstituted_predicate)
|
||||
.subst(tcx, substs);
|
||||
insert_outlives_predicate(
|
||||
tcx,
|
||||
predicate.0,
|
||||
|
@ -224,7 +230,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
|||
/// will give us `U: 'static` and `U: Foo`. The latter we
|
||||
/// can ignore, but we will want to process `U: 'static`,
|
||||
/// applying the substitution as above.
|
||||
pub fn check_explicit_predicates<'tcx>(
|
||||
fn check_explicit_predicates<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
substs: &[GenericArg<'tcx>],
|
||||
|
@ -242,7 +248,7 @@ pub fn check_explicit_predicates<'tcx>(
|
|||
);
|
||||
let explicit_predicates = explicit_map.explicit_predicates_of(tcx, def_id);
|
||||
|
||||
for (outlives_predicate, &span) in explicit_predicates {
|
||||
for (outlives_predicate, &span) in &explicit_predicates.0 {
|
||||
debug!("outlives_predicate = {:?}", &outlives_predicate);
|
||||
|
||||
// Careful: If we are inferring the effects of a `dyn Trait<..>`
|
||||
|
@ -287,7 +293,7 @@ pub fn check_explicit_predicates<'tcx>(
|
|||
continue;
|
||||
}
|
||||
|
||||
let predicate = EarlyBinder(*outlives_predicate).subst(tcx, substs);
|
||||
let predicate = explicit_predicates.rebind(*outlives_predicate).subst(tcx, substs);
|
||||
debug!("predicate = {:?}", &predicate);
|
||||
insert_outlives_predicate(tcx, predicate.0, predicate.1, span, required_predicates);
|
||||
}
|
||||
|
|
|
@ -88,9 +88,7 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> {
|
|||
// for the type.
|
||||
|
||||
// Compute the inferred predicates
|
||||
let mut exp_map = explicit::ExplicitPredicatesMap::new();
|
||||
|
||||
let global_inferred_outlives = implicit_infer::infer_predicates(tcx, &mut exp_map);
|
||||
let global_inferred_outlives = implicit_infer::infer_predicates(tcx);
|
||||
|
||||
// Convert the inferred predicates into the "collected" form the
|
||||
// global data structure expects.
|
||||
|
@ -100,7 +98,7 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> {
|
|||
let predicates = global_inferred_outlives
|
||||
.iter()
|
||||
.map(|(&def_id, set)| {
|
||||
let predicates = &*tcx.arena.alloc_from_iter(set.iter().filter_map(
|
||||
let predicates = &*tcx.arena.alloc_from_iter(set.0.iter().filter_map(
|
||||
|(ty::OutlivesPredicate(kind1, region2), &span)| {
|
||||
match kind1.unpack() {
|
||||
GenericArgKind::Type(ty1) => Some((
|
||||
|
|
|
@ -7,12 +7,12 @@ use std::collections::BTreeMap;
|
|||
|
||||
/// Tracks the `T: 'a` or `'a: 'a` predicates that we have inferred
|
||||
/// must be added to the struct header.
|
||||
pub type RequiredPredicates<'tcx> =
|
||||
pub(crate) type RequiredPredicates<'tcx> =
|
||||
BTreeMap<ty::OutlivesPredicate<GenericArg<'tcx>, ty::Region<'tcx>>, Span>;
|
||||
|
||||
/// Given a requirement `T: 'a` or `'b: 'a`, deduce the
|
||||
/// outlives_component and add it to `required_predicates`
|
||||
pub fn insert_outlives_predicate<'tcx>(
|
||||
pub(crate) fn insert_outlives_predicate<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
kind: GenericArg<'tcx>,
|
||||
outlived_region: Region<'tcx>,
|
||||
|
|
|
@ -8,4 +8,4 @@ all:
|
|||
RUST_TARGET_PATH=. $(RUSTC) foo.rs --target=my-x86_64-unknown-linux-gnu-platform --crate-type=lib --emit=asm
|
||||
$(RUSTC) -Z unstable-options --target=my-awesome-platform.json --print target-spec-json > $(TMPDIR)/test-platform.json && $(RUSTC) -Z unstable-options --target=$(TMPDIR)/test-platform.json --print target-spec-json | diff -q $(TMPDIR)/test-platform.json -
|
||||
$(RUSTC) foo.rs --target=definitely-not-builtin-target 2>&1 | $(CGREP) 'may not set is_builtin'
|
||||
$(RUSTC) foo.rs --target=mismatching-data-layout
|
||||
$(RUSTC) foo.rs --target=mismatching-data-layout --crate-type=lib
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// check-pass
|
||||
// compile-flags: -Chelp
|
||||
// check-stdout
|
||||
// regex-error-pattern: -C\s+incremental
|
||||
|
||||
pub struct Foo;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// check-pass
|
||||
// compile-flags: -Zhelp
|
||||
// check-stdout
|
||||
// regex-error-pattern: -Z\s+self-profile
|
||||
|
||||
pub struct Foo;
|
||||
|
|
|
@ -9,9 +9,11 @@ fn _if_let_guard() {
|
|||
|
||||
() if (let 0 = 1) => {}
|
||||
//~^ ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
() if (((let 0 = 1))) => {}
|
||||
//~^ ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
() if true && let 0 = 1 => {}
|
||||
//~^ ERROR `if let` guards are experimental
|
||||
|
@ -23,13 +25,17 @@ fn _if_let_guard() {
|
|||
|
||||
() if (let 0 = 1) && true => {}
|
||||
//~^ ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
() if true && (let 0 = 1) => {}
|
||||
//~^ ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
() if (let 0 = 1) && (let 0 = 1) => {}
|
||||
//~^ ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
() if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
//~^ ERROR `if let` guards are experimental
|
||||
|
@ -38,6 +44,7 @@ fn _if_let_guard() {
|
|||
//~| ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
() if let Range { start: _, end: _ } = (true..true) && false => {}
|
||||
//~^ ERROR `if let` guards are experimental
|
||||
|
|
|
@ -1,17 +1,59 @@
|
|||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:59:16
|
||||
--> $DIR/feature-gate.rs:10:16
|
||||
|
|
||||
LL | () if (let 0 = 1) => {}
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:14:18
|
||||
|
|
||||
LL | () if (((let 0 = 1))) => {}
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:26:16
|
||||
|
|
||||
LL | () if (let 0 = 1) && true => {}
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:30:24
|
||||
|
|
||||
LL | () if true && (let 0 = 1) => {}
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:34:16
|
||||
|
|
||||
LL | () if (let 0 = 1) && (let 0 = 1) => {}
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:34:31
|
||||
|
|
||||
LL | () if (let 0 = 1) && (let 0 = 1) => {}
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:40:42
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:66:16
|
||||
|
|
||||
LL | use_expr!((let 0 = 1 && 0 == 0));
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:62:16
|
||||
--> $DIR/feature-gate.rs:69:16
|
||||
|
|
||||
LL | use_expr!((let 0 = 1));
|
||||
| ^^^
|
||||
|
||||
error: no rules expected the token `let`
|
||||
--> $DIR/feature-gate.rs:71:15
|
||||
--> $DIR/feature-gate.rs:78:15
|
||||
|
|
||||
LL | macro_rules! use_expr {
|
||||
| --------------------- when calling this macro
|
||||
|
@ -30,7 +72,7 @@ LL | () if let 0 = 1 => {}
|
|||
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
|
||||
|
||||
error[E0658]: `if let` guards are experimental
|
||||
--> $DIR/feature-gate.rs:16:12
|
||||
--> $DIR/feature-gate.rs:18:12
|
||||
|
|
||||
LL | () if true && let 0 = 1 => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -40,7 +82,7 @@ LL | () if true && let 0 = 1 => {}
|
|||
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
|
||||
|
||||
error[E0658]: `if let` guards are experimental
|
||||
--> $DIR/feature-gate.rs:20:12
|
||||
--> $DIR/feature-gate.rs:22:12
|
||||
|
|
||||
LL | () if let 0 = 1 && true => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -50,7 +92,7 @@ LL | () if let 0 = 1 && true => {}
|
|||
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
|
||||
|
||||
error[E0658]: `if let` guards are experimental
|
||||
--> $DIR/feature-gate.rs:34:12
|
||||
--> $DIR/feature-gate.rs:40:12
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -60,7 +102,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
|
|||
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
|
||||
|
||||
error[E0658]: `if let` guards are experimental
|
||||
--> $DIR/feature-gate.rs:42:12
|
||||
--> $DIR/feature-gate.rs:49:12
|
||||
|
|
||||
LL | () if let Range { start: _, end: _ } = (true..true) && false => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -70,7 +112,7 @@ LL | () if let Range { start: _, end: _ } = (true..true) && false => {}
|
|||
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
|
||||
|
||||
error[E0658]: `if let` guards are experimental
|
||||
--> $DIR/feature-gate.rs:67:12
|
||||
--> $DIR/feature-gate.rs:74:12
|
||||
|
|
||||
LL | () if let 0 = 1 => {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
@ -89,7 +131,7 @@ LL | () if (let 0 = 1) => {}
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:13:18
|
||||
--> $DIR/feature-gate.rs:14:18
|
||||
|
|
||||
LL | () if (((let 0 = 1))) => {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -98,7 +140,7 @@ LL | () if (((let 0 = 1))) => {}
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:16:23
|
||||
--> $DIR/feature-gate.rs:18:23
|
||||
|
|
||||
LL | () if true && let 0 = 1 => {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -107,7 +149,7 @@ LL | () if true && let 0 = 1 => {}
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:20:15
|
||||
--> $DIR/feature-gate.rs:22:15
|
||||
|
|
||||
LL | () if let 0 = 1 && true => {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -116,7 +158,7 @@ LL | () if let 0 = 1 && true => {}
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:24:16
|
||||
--> $DIR/feature-gate.rs:26:16
|
||||
|
|
||||
LL | () if (let 0 = 1) && true => {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -125,7 +167,7 @@ LL | () if (let 0 = 1) && true => {}
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:27:24
|
||||
--> $DIR/feature-gate.rs:30:24
|
||||
|
|
||||
LL | () if true && (let 0 = 1) => {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -134,7 +176,7 @@ LL | () if true && (let 0 = 1) => {}
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:30:16
|
||||
--> $DIR/feature-gate.rs:34:16
|
||||
|
|
||||
LL | () if (let 0 = 1) && (let 0 = 1) => {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -143,7 +185,7 @@ LL | () if (let 0 = 1) && (let 0 = 1) => {}
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:30:31
|
||||
--> $DIR/feature-gate.rs:34:31
|
||||
|
|
||||
LL | () if (let 0 = 1) && (let 0 = 1) => {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -152,7 +194,7 @@ LL | () if (let 0 = 1) && (let 0 = 1) => {}
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:34:15
|
||||
--> $DIR/feature-gate.rs:40:15
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -161,7 +203,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:34:28
|
||||
--> $DIR/feature-gate.rs:40:28
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -170,7 +212,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:34:42
|
||||
--> $DIR/feature-gate.rs:40:42
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -179,7 +221,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:34:55
|
||||
--> $DIR/feature-gate.rs:40:55
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -188,7 +230,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:34:68
|
||||
--> $DIR/feature-gate.rs:40:68
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -197,7 +239,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:42:15
|
||||
--> $DIR/feature-gate.rs:49:15
|
||||
|
|
||||
LL | () if let Range { start: _, end: _ } = (true..true) && false => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -206,7 +248,7 @@ LL | () if let Range { start: _, end: _ } = (true..true) && false => {}
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:59:16
|
||||
--> $DIR/feature-gate.rs:66:16
|
||||
|
|
||||
LL | use_expr!((let 0 = 1 && 0 == 0));
|
||||
| ^^^^^^^^^
|
||||
|
@ -215,7 +257,7 @@ LL | use_expr!((let 0 = 1 && 0 == 0));
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:62:16
|
||||
--> $DIR/feature-gate.rs:69:16
|
||||
|
|
||||
LL | use_expr!((let 0 = 1));
|
||||
| ^^^^^^^^^
|
||||
|
@ -223,6 +265,6 @@ LL | use_expr!((let 0 = 1));
|
|||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 25 previous errors
|
||||
error: aborting due to 32 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
|
@ -28,47 +28,61 @@ fn main() {}
|
|||
fn _if() {
|
||||
if (let 0 = 1) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
if (((let 0 = 1))) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
if (let 0 = 1) && true {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
if true && (let 0 = 1) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
if (let 0 = 1) && (let 0 = 1) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
|
||||
fn _while() {
|
||||
while (let 0 = 1) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
while (((let 0 = 1))) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
while (let 0 = 1) && true {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
while true && (let 0 = 1) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
while (let 0 = 1) && (let 0 = 1) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
|
||||
fn _macros() {
|
||||
|
@ -89,39 +103,64 @@ fn _macros() {
|
|||
}
|
||||
|
||||
fn nested_within_if_expr() {
|
||||
if &let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
if &let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
if !let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
if *let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR type `bool` cannot be dereferenced
|
||||
if -let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR cannot apply unary operator `-` to type `bool`
|
||||
if !let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
if *let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR type `bool` cannot be dereferenced
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
if -let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR cannot apply unary operator `-` to type `bool`
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
fn _check_try_binds_tighter() -> Result<(), ()> {
|
||||
if let 0 = 0? {}
|
||||
//~^ ERROR the `?` operator can only be applied to values that implement `Try`
|
||||
Ok(())
|
||||
}
|
||||
if (let 0 = 0)? {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR the `?` operator can only be applied to values that implement `Try`
|
||||
if (let 0 = 0)? {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR the `?` operator can only be applied to values that implement `Try`
|
||||
//~| ERROR the `?` operator can only be used in a function that returns `Result`
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
if true || let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
if (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
if true && (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
if true || (true && let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
if true || let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
if (true || let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
if true && (true || let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
if true || (true && let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
|
||||
let mut x = true;
|
||||
if x = let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
if x = let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
if true..(let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
if ..(let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
if (let 0 = 0).. {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
if true..(let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
if ..(let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
if (let 0 = 0).. {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
// Binds as `(let ... = true)..true &&/|| false`.
|
||||
if let Range { start: _, end: _ } = true..true && false {}
|
||||
|
@ -151,42 +190,68 @@ fn nested_within_if_expr() {
|
|||
|
||||
if let true = let true = true {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
|
||||
fn nested_within_while_expr() {
|
||||
while &let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
while &let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
while !let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
while *let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR type `bool` cannot be dereferenced
|
||||
while -let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR cannot apply unary operator `-` to type `bool`
|
||||
while !let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
while *let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR type `bool` cannot be dereferenced
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
while -let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR cannot apply unary operator `-` to type `bool`
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
fn _check_try_binds_tighter() -> Result<(), ()> {
|
||||
while let 0 = 0? {}
|
||||
//~^ ERROR the `?` operator can only be applied to values that implement `Try`
|
||||
Ok(())
|
||||
}
|
||||
while (let 0 = 0)? {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR the `?` operator can only be applied to values that implement `Try`
|
||||
while (let 0 = 0)? {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR the `?` operator can only be applied to values that implement `Try`
|
||||
//~| ERROR the `?` operator can only be used in a function that returns `Result`
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
while true || let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
while (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
while true && (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
while true || (true && let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
while true || let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
while (true || let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
while true && (true || let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
while true || (true && let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
|
||||
let mut x = true;
|
||||
while x = let 0 = 0 {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
while x = let 0 = 0 {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
while true..(let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
while ..(let 0 = 0) {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
while (let 0 = 0).. {} //~ ERROR `let` expressions are not supported here
|
||||
//~^ ERROR mismatched types
|
||||
while true..(let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
while ..(let 0 = 0) {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
while (let 0 = 0).. {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
||||
// Binds as `(let ... = true)..true &&/|| false`.
|
||||
while let Range { start: _, end: _ } = true..true && false {}
|
||||
|
@ -216,6 +281,7 @@ fn nested_within_while_expr() {
|
|||
|
||||
while let true = let true = true {}
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
|
||||
fn not_error_because_clarified_intent() {
|
||||
|
@ -316,15 +382,18 @@ fn inside_const_generic_arguments() {
|
|||
impl<const B: bool> A<{B}> { const O: u32 = 5; }
|
||||
|
||||
if let A::<{
|
||||
true && let 1 = 1 //~ ERROR `let` expressions are not supported here
|
||||
true && let 1 = 1
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
}>::O = 5 {}
|
||||
|
||||
while let A::<{
|
||||
true && let 1 = 1 //~ ERROR `let` expressions are not supported here
|
||||
true && let 1 = 1
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
}>::O = 5 {}
|
||||
|
||||
if A::<{
|
||||
true && let 1 = 1 //~ ERROR `let` expressions are not supported here
|
||||
true && let 1 = 1
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
}>::O == 5 {}
|
||||
|
||||
// In the cases above we have `ExprKind::Block` to help us out.
|
||||
|
@ -345,14 +414,18 @@ fn with_parenthesis() {
|
|||
|
||||
if (let Some(a) = opt && true) {
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
|
||||
if (let Some(a) = opt) && true {
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
if (let Some(a) = opt) && (let Some(b) = a) {
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
if let Some(a) = opt && (true && true) {
|
||||
}
|
||||
|
@ -360,13 +433,18 @@ fn with_parenthesis() {
|
|||
if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
if (let Some(a) = opt && (let Some(b) = a)) && true {
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
if (let Some(a) = opt && (true)) && true {
|
||||
//~^ ERROR `let` expressions are not supported here
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
}
|
||||
|
||||
if (true && (true)) && let Some(a) = opt {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -19,6 +19,11 @@ fn _if() {
|
|||
|
||||
if let Range { start: _, end: _ } = (true..true) && false {}
|
||||
//~^ ERROR `let` expressions in this position are unstable [E0658]
|
||||
|
||||
if let 1 = 1 && let true = { true } && false {
|
||||
//~^ ERROR `let` expressions in this position are unstable [E0658]
|
||||
//~| ERROR `let` expressions in this position are unstable [E0658]
|
||||
}
|
||||
}
|
||||
|
||||
fn _while() {
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:50:20
|
||||
--> $DIR/feature-gate.rs:55:20
|
||||
|
|
||||
LL | #[cfg(FALSE)] (let 0 = 1);
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:40:17
|
||||
--> $DIR/feature-gate.rs:45:17
|
||||
|
|
||||
LL | noop_expr!((let 0 = 1));
|
||||
| ^^^
|
||||
|
||||
error: no rules expected the token `let`
|
||||
--> $DIR/feature-gate.rs:53:15
|
||||
--> $DIR/feature-gate.rs:58:15
|
||||
|
|
||||
LL | macro_rules! use_expr {
|
||||
| --------------------- when calling this macro
|
||||
|
@ -47,7 +47,25 @@ LL | if let Range { start: _, end: _ } = (true..true) && false {}
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:27:19
|
||||
--> $DIR/feature-gate.rs:23:8
|
||||
|
|
||||
LL | if let 1 = 1 && let true = { true } && false {
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:23:21
|
||||
|
|
||||
LL | if let 1 = 1 && let true = { true } && false {
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:32:19
|
||||
|
|
||||
LL | while true && let 0 = 1 {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -56,7 +74,7 @@ LL | while true && let 0 = 1 {}
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:30:11
|
||||
--> $DIR/feature-gate.rs:35:11
|
||||
|
|
||||
LL | while let 0 = 1 && true {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -65,7 +83,7 @@ LL | while let 0 = 1 && true {}
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:33:11
|
||||
--> $DIR/feature-gate.rs:38:11
|
||||
|
|
||||
LL | while let Range { start: _, end: _ } = (true..true) && false {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -74,7 +92,7 @@ LL | while let Range { start: _, end: _ } = (true..true) && false {}
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:50:20
|
||||
--> $DIR/feature-gate.rs:55:20
|
||||
|
|
||||
LL | #[cfg(FALSE)] (let 0 = 1);
|
||||
| ^^^^^^^^^
|
||||
|
@ -83,7 +101,7 @@ LL | #[cfg(FALSE)] (let 0 = 1);
|
|||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:40:17
|
||||
--> $DIR/feature-gate.rs:45:17
|
||||
|
|
||||
LL | noop_expr!((let 0 = 1));
|
||||
| ^^^^^^^^^
|
||||
|
@ -91,6 +109,6 @@ LL | noop_expr!((let 0 = 1));
|
|||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
error: aborting due to 13 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
|
@ -1,17 +1,45 @@
|
|||
// check-pass
|
||||
// known-bug
|
||||
|
||||
#![feature(let_chains)]
|
||||
|
||||
fn main() {
|
||||
let _opt = Some(1i32);
|
||||
|
||||
#[cfg(FALSE)]
|
||||
{
|
||||
let _ = &&let Some(x) = Some(42);
|
||||
//~^ ERROR expected expression, found `let` statement
|
||||
}
|
||||
#[cfg(FALSE)]
|
||||
{
|
||||
if let Some(elem) = _opt && [1, 2, 3][let _ = &&let Some(x) = Some(42)] = 1 {
|
||||
//~^ ERROR expected expression, found `let` statement
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
{
|
||||
if let Some(elem) = _opt && {
|
||||
[1, 2, 3][let _ = ()];
|
||||
//~^ ERROR expected expression, found `let` statement
|
||||
true
|
||||
} {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
{
|
||||
if let Some(elem) = _opt && [1, 2, 3][let _ = ()] = 1 {
|
||||
//~^ ERROR expected expression, found `let` statement
|
||||
true
|
||||
}
|
||||
}
|
||||
#[cfg(FALSE)]
|
||||
{
|
||||
if let a = 1 && {
|
||||
let x = let y = 1;
|
||||
//~^ ERROR expected expression, found `let` statement
|
||||
} {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
error: expected expression, found `let` statement
|
||||
--> $DIR/invalid-let-in-a-valid-let-context.rs:8:19
|
||||
|
|
||||
LL | let _ = &&let Some(x) = Some(42);
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/invalid-let-in-a-valid-let-context.rs:13:47
|
||||
|
|
||||
LL | if let Some(elem) = _opt && [1, 2, 3][let _ = &&let Some(x) = Some(42)] = 1 {
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/invalid-let-in-a-valid-let-context.rs:13:57
|
||||
|
|
||||
LL | if let Some(elem) = _opt && [1, 2, 3][let _ = &&let Some(x) = Some(42)] = 1 {
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/invalid-let-in-a-valid-let-context.rs:23:23
|
||||
|
|
||||
LL | [1, 2, 3][let _ = ()];
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/invalid-let-in-a-valid-let-context.rs:32:47
|
||||
|
|
||||
LL | if let Some(elem) = _opt && [1, 2, 3][let _ = ()] = 1 {
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/invalid-let-in-a-valid-let-context.rs:40:21
|
||||
|
|
||||
LL | let x = let y = 1;
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
macro_rules! num { () => { 1 } }
|
||||
|
||||
fn main() {
|
||||
let x = 1i32;
|
||||
x.e10; //~ERROR `i32` is a primitive type and therefore doesn't have fields
|
||||
|
||||
let y = 1;
|
||||
y.e10; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
|
||||
2u32.e10; //~ERROR `u32` is a primitive type and therefore doesn't have fields
|
||||
|
||||
num!().e10; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
|
||||
2.e10foo; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
|
||||
42._;
|
||||
//~^ERROR expected identifier, found reserved identifier `_`
|
||||
//~|ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
|
||||
42.a; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
error: expected identifier, found reserved identifier `_`
|
||||
--> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:16:8
|
||||
|
|
||||
LL | 42._;
|
||||
| ^ expected identifier, found reserved identifier
|
||||
|
||||
error[E0610]: `i32` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:5:7
|
||||
|
|
||||
LL | x.e10;
|
||||
| ^^^
|
||||
|
||||
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:8:7
|
||||
|
|
||||
LL | y.e10;
|
||||
| ^^^
|
||||
|
||||
error[E0610]: `u32` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:10:10
|
||||
|
|
||||
LL | 2u32.e10;
|
||||
| ^^^
|
||||
|
||||
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:12:12
|
||||
|
|
||||
LL | num!().e10;
|
||||
| ^^^
|
||||
|
||||
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:14:7
|
||||
|
|
||||
LL | 2.e10foo;
|
||||
| ^^^^^^
|
||||
|
||||
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:16:8
|
||||
|
|
||||
LL | 42._;
|
||||
| ^
|
||||
|
||||
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:20:8
|
||||
|
|
||||
LL | 42.a;
|
||||
| ^
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0610`.
|
|
@ -0,0 +1,11 @@
|
|||
// run-rustfix
|
||||
|
||||
fn main() {
|
||||
2.0e1; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
2.0E1; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
2.0f32; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
2.0f64; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
2.0e+12; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
2.0e-12; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
2.0e1f32; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
// run-rustfix
|
||||
|
||||
fn main() {
|
||||
2.e1; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
2.E1; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
2.f32; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
2.f64; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
2.e+12; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
2.e-12; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
2.e1f32; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:4:7
|
||||
|
|
||||
LL | 2.e1;
|
||||
| ^^
|
||||
|
|
||||
help: If the number is meant to be a floating point number, consider adding a `0` after the period
|
||||
|
|
||||
LL | 2.0e1;
|
||||
| +
|
||||
|
||||
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:5:7
|
||||
|
|
||||
LL | 2.E1;
|
||||
| ^^
|
||||
|
|
||||
help: If the number is meant to be a floating point number, consider adding a `0` after the period
|
||||
|
|
||||
LL | 2.0E1;
|
||||
| +
|
||||
|
||||
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:6:7
|
||||
|
|
||||
LL | 2.f32;
|
||||
| ^^^
|
||||
|
|
||||
help: If the number is meant to be a floating point number, consider adding a `0` after the period
|
||||
|
|
||||
LL | 2.0f32;
|
||||
| +
|
||||
|
||||
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:7:7
|
||||
|
|
||||
LL | 2.f64;
|
||||
| ^^^
|
||||
|
|
||||
help: If the number is meant to be a floating point number, consider adding a `0` after the period
|
||||
|
|
||||
LL | 2.0f64;
|
||||
| +
|
||||
|
||||
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:8:7
|
||||
|
|
||||
LL | 2.e+12;
|
||||
| ^
|
||||
|
|
||||
help: If the number is meant to be a floating point number, consider adding a `0` after the period
|
||||
|
|
||||
LL | 2.0e+12;
|
||||
| +
|
||||
|
||||
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:9:7
|
||||
|
|
||||
LL | 2.e-12;
|
||||
| ^
|
||||
|
|
||||
help: If the number is meant to be a floating point number, consider adding a `0` after the period
|
||||
|
|
||||
LL | 2.0e-12;
|
||||
| +
|
||||
|
||||
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:10:7
|
||||
|
|
||||
LL | 2.e1f32;
|
||||
| ^^^^^
|
||||
|
|
||||
help: If the number is meant to be a floating point number, consider adding a `0` after the period
|
||||
|
|
||||
LL | 2.0e1f32;
|
||||
| +
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0610`.
|
|
@ -60,6 +60,8 @@ impl EarlyProps {
|
|||
pub struct TestProps {
|
||||
// Lines that should be expected, in order, on standard out
|
||||
pub error_patterns: Vec<String>,
|
||||
// Regexes that should be expected, in order, on standard out
|
||||
pub regex_error_patterns: Vec<String>,
|
||||
// Extra flags to pass to the compiler
|
||||
pub compile_flags: Vec<String>,
|
||||
// Extra flags to pass when the compiled code is run (such as --bench)
|
||||
|
@ -163,6 +165,7 @@ pub struct TestProps {
|
|||
|
||||
mod directives {
|
||||
pub const ERROR_PATTERN: &'static str = "error-pattern";
|
||||
pub const REGEX_ERROR_PATTERN: &'static str = "regex-error-pattern";
|
||||
pub const COMPILE_FLAGS: &'static str = "compile-flags";
|
||||
pub const RUN_FLAGS: &'static str = "run-flags";
|
||||
pub const SHOULD_ICE: &'static str = "should-ice";
|
||||
|
@ -200,6 +203,7 @@ impl TestProps {
|
|||
pub fn new() -> Self {
|
||||
TestProps {
|
||||
error_patterns: vec![],
|
||||
regex_error_patterns: vec![],
|
||||
compile_flags: vec![],
|
||||
run_flags: None,
|
||||
pp_exact: None,
|
||||
|
@ -285,6 +289,12 @@ impl TestProps {
|
|||
&mut self.error_patterns,
|
||||
|r| r,
|
||||
);
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
REGEX_ERROR_PATTERN,
|
||||
&mut self.regex_error_patterns,
|
||||
|r| r,
|
||||
);
|
||||
|
||||
if let Some(flags) = config.parse_name_value_directive(ln, COMPILE_FLAGS) {
|
||||
self.compile_flags.extend(flags.split_whitespace().map(|s| s.to_owned()));
|
||||
|
|
|
@ -323,12 +323,13 @@ impl<'test> TestCx<'test> {
|
|||
let output_to_check = self.get_output(&proc_res);
|
||||
let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
|
||||
if !expected_errors.is_empty() {
|
||||
if !self.props.error_patterns.is_empty() {
|
||||
if !self.props.error_patterns.is_empty() || !self.props.regex_error_patterns.is_empty()
|
||||
{
|
||||
self.fatal("both error pattern and expected errors specified");
|
||||
}
|
||||
self.check_expected_errors(expected_errors, &proc_res);
|
||||
} else {
|
||||
self.check_error_patterns(&output_to_check, &proc_res, pm);
|
||||
self.check_all_error_patterns(&output_to_check, &proc_res, pm);
|
||||
}
|
||||
if self.props.should_ice {
|
||||
match proc_res.status.code() {
|
||||
|
@ -363,7 +364,7 @@ impl<'test> TestCx<'test> {
|
|||
|
||||
let output_to_check = self.get_output(&proc_res);
|
||||
self.check_correct_failure_status(&proc_res);
|
||||
self.check_error_patterns(&output_to_check, &proc_res, pm);
|
||||
self.check_all_error_patterns(&output_to_check, &proc_res, pm);
|
||||
}
|
||||
|
||||
fn get_output(&self, proc_res: &ProcRes) -> String {
|
||||
|
@ -1222,14 +1223,13 @@ impl<'test> TestCx<'test> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_error_patterns(
|
||||
fn check_all_error_patterns(
|
||||
&self,
|
||||
output_to_check: &str,
|
||||
proc_res: &ProcRes,
|
||||
pm: Option<PassMode>,
|
||||
) {
|
||||
debug!("check_error_patterns");
|
||||
if self.props.error_patterns.is_empty() {
|
||||
if self.props.error_patterns.is_empty() && self.props.regex_error_patterns.is_empty() {
|
||||
if pm.is_some() {
|
||||
// FIXME(#65865)
|
||||
return;
|
||||
|
@ -1243,13 +1243,8 @@ impl<'test> TestCx<'test> {
|
|||
|
||||
let mut missing_patterns: Vec<String> = Vec::new();
|
||||
|
||||
for pattern in &self.props.error_patterns {
|
||||
if output_to_check.contains(pattern.trim()) {
|
||||
debug!("found error pattern {}", pattern);
|
||||
} else {
|
||||
missing_patterns.push(pattern.to_string());
|
||||
}
|
||||
}
|
||||
self.check_error_patterns(output_to_check, &mut missing_patterns);
|
||||
self.check_regex_error_patterns(output_to_check, proc_res, &mut missing_patterns);
|
||||
|
||||
if missing_patterns.is_empty() {
|
||||
return;
|
||||
|
@ -1268,6 +1263,44 @@ impl<'test> TestCx<'test> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_error_patterns(&self, output_to_check: &str, missing_patterns: &mut Vec<String>) {
|
||||
debug!("check_error_patterns");
|
||||
for pattern in &self.props.error_patterns {
|
||||
if output_to_check.contains(pattern.trim()) {
|
||||
debug!("found error pattern {}", pattern);
|
||||
} else {
|
||||
missing_patterns.push(pattern.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_regex_error_patterns(
|
||||
&self,
|
||||
output_to_check: &str,
|
||||
proc_res: &ProcRes,
|
||||
missing_patterns: &mut Vec<String>,
|
||||
) {
|
||||
debug!("check_regex_error_patterns");
|
||||
|
||||
for pattern in &self.props.regex_error_patterns {
|
||||
let pattern = pattern.trim();
|
||||
let re = match Regex::new(pattern) {
|
||||
Ok(re) => re,
|
||||
Err(err) => {
|
||||
self.fatal_proc_rec(
|
||||
&format!("invalid regex error pattern '{}': {:?}", pattern, err),
|
||||
proc_res,
|
||||
);
|
||||
}
|
||||
};
|
||||
if re.is_match(output_to_check) {
|
||||
debug!("found regex error pattern {}", pattern);
|
||||
} else {
|
||||
missing_patterns.push(pattern.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_no_compiler_crash(&self, proc_res: &ProcRes, should_ice: bool) {
|
||||
match proc_res.status.code() {
|
||||
Some(101) if !should_ice => {
|
||||
|
@ -1892,7 +1925,9 @@ impl<'test> TestCx<'test> {
|
|||
// If we are extracting and matching errors in the new
|
||||
// fashion, then you want JSON mode. Old-skool error
|
||||
// patterns still match the raw compiler output.
|
||||
if self.props.error_patterns.is_empty() {
|
||||
if self.props.error_patterns.is_empty()
|
||||
&& self.props.regex_error_patterns.is_empty()
|
||||
{
|
||||
rustc.args(&["--error-format", "json"]);
|
||||
rustc.args(&["--json", "future-incompat"]);
|
||||
}
|
||||
|
@ -3268,10 +3303,11 @@ impl<'test> TestCx<'test> {
|
|||
self.fatal_proc_rec("test run succeeded!", &proc_res);
|
||||
}
|
||||
|
||||
if !self.props.error_patterns.is_empty() {
|
||||
if !self.props.error_patterns.is_empty() || !self.props.regex_error_patterns.is_empty()
|
||||
{
|
||||
// "// error-pattern" comments
|
||||
let output_to_check = self.get_output(&proc_res);
|
||||
self.check_error_patterns(&output_to_check, &proc_res, pm);
|
||||
self.check_all_error_patterns(&output_to_check, &proc_res, pm);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3285,15 +3321,16 @@ impl<'test> TestCx<'test> {
|
|||
self.props.error_patterns
|
||||
);
|
||||
if !explicit && self.config.compare_mode.is_none() {
|
||||
let check_patterns =
|
||||
should_run == WillExecute::No && !self.props.error_patterns.is_empty();
|
||||
let check_patterns = should_run == WillExecute::No
|
||||
&& (!self.props.error_patterns.is_empty()
|
||||
|| !self.props.regex_error_patterns.is_empty());
|
||||
|
||||
let check_annotations = !check_patterns || !expected_errors.is_empty();
|
||||
|
||||
if check_patterns {
|
||||
// "// error-pattern" comments
|
||||
let output_to_check = self.get_output(&proc_res);
|
||||
self.check_error_patterns(&output_to_check, &proc_res, pm);
|
||||
self.check_all_error_patterns(&output_to_check, &proc_res, pm);
|
||||
}
|
||||
|
||||
if check_annotations {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue