Auto merge of #88066 - LeSeulArtichaut:patterns-cleanups, r=nagisa

Use if-let guards in the codebase and various other pattern cleanups

Dogfooding if-let guards as experimentation for the feature.

Tracking issue #51114. Conflicts with #87937.
This commit is contained in:
bors 2021-08-26 05:23:35 +00:00
commit 76e755cf4a
35 changed files with 289 additions and 322 deletions

View File

@ -564,11 +564,11 @@ impl NestedMetaItem {
I: Iterator<Item = TokenTree>,
{
match tokens.peek() {
Some(TokenTree::Token(token)) => {
if let Ok(lit) = Lit::from_token(token) {
tokens.next();
return Some(NestedMetaItem::Literal(lit));
}
Some(TokenTree::Token(token))
if let Ok(lit) = Lit::from_token(token) =>
{
tokens.next();
return Some(NestedMetaItem::Literal(lit));
}
Some(TokenTree::Delimited(_, token::NoDelim, inner_tokens)) => {
let inner_tokens = inner_tokens.clone();

View File

@ -11,10 +11,12 @@
#![feature(box_patterns)]
#![cfg_attr(bootstrap, feature(const_fn_transmute))]
#![feature(crate_visibility_modifier)]
#![feature(if_let_guard)]
#![feature(iter_zip)]
#![feature(label_break_value)]
#![feature(nll)]
#![feature(min_specialization)]
#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
#![recursion_limit = "256"]
#[macro_use]

View File

@ -1179,13 +1179,10 @@ fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) {
for (op, _) in &mut asm.operands {
match op {
InlineAsmOperand::In { expr, .. }
| InlineAsmOperand::Out { expr: Some(expr), .. }
| InlineAsmOperand::InOut { expr, .. }
| InlineAsmOperand::Sym { expr, .. } => vis.visit_expr(expr),
InlineAsmOperand::Out { expr, .. } => {
if let Some(expr) = expr {
vis.visit_expr(expr);
}
}
InlineAsmOperand::Out { expr: None, .. } => {}
InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
vis.visit_expr(in_expr);
if let Some(out_expr) = out_expr {

View File

@ -714,13 +714,10 @@ fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) {
for (op, _) in &asm.operands {
match op {
InlineAsmOperand::In { expr, .. }
| InlineAsmOperand::Out { expr: Some(expr), .. }
| InlineAsmOperand::InOut { expr, .. }
| InlineAsmOperand::Sym { expr, .. } => visitor.visit_expr(expr),
InlineAsmOperand::Out { expr, .. } => {
if let Some(expr) = expr {
visitor.visit_expr(expr);
}
}
InlineAsmOperand::Out { expr: None, .. } => {}
InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
visitor.visit_expr(in_expr);
if let Some(out_expr) = out_expr {

View File

@ -5,9 +5,11 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(crate_visibility_modifier)]
#![feature(backtrace)]
#![feature(if_let_guard)]
#![feature(format_args_capture)]
#![feature(iter_zip)]
#![feature(nll)]
#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
#[macro_use]
extern crate rustc_macros;
@ -1027,15 +1029,15 @@ impl HandlerInner {
let mut error_codes = self
.emitted_diagnostic_codes
.iter()
.filter_map(|x| match &x {
DiagnosticId::Error(s) => {
if let Ok(Some(_explanation)) = registry.try_find_description(s) {
Some(s.clone())
} else {
None
}
.filter_map(|x| {
match &x {
DiagnosticId::Error(s)
if let Ok(Some(_explanation)) = registry.try_find_description(s) =>
{
Some(s.clone())
}
_ => None,
}
})
.collect::<Vec<_>>();
if !error_codes.is_empty() {

View File

@ -305,15 +305,14 @@ impl<'a> StripUnconfigured<'a> {
Some((AttrAnnotatedTokenTree::Delimited(sp, delim, inner), *spacing))
.into_iter()
}
AttrAnnotatedTokenTree::Token(ref token) if let TokenKind::Interpolated(ref nt) = token.kind => {
panic!(
"Nonterminal should have been flattened at {:?}: {:?}",
token.span, nt
);
}
AttrAnnotatedTokenTree::Token(token) => {
if let TokenKind::Interpolated(nt) = token.kind {
panic!(
"Nonterminal should have been flattened at {:?}: {:?}",
token.span, nt
);
} else {
Some((AttrAnnotatedTokenTree::Token(token), *spacing)).into_iter()
}
Some((AttrAnnotatedTokenTree::Token(token), *spacing)).into_iter()
}
})
.collect();

View File

@ -1,12 +1,15 @@
#![cfg_attr(bootstrap, feature(bindings_after_at))]
#![feature(crate_visibility_modifier)]
#![feature(decl_macro)]
#![feature(destructuring_assignment)]
#![feature(format_args_capture)]
#![feature(if_let_guard)]
#![feature(iter_zip)]
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_internals)]
#![feature(proc_macro_span)]
#![feature(try_blocks)]
#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
#[macro_use]
extern crate rustc_macros;

View File

@ -86,13 +86,12 @@ crate fn mod_dir_path(
inline: Inline,
) -> (PathBuf, DirOwnership) {
match inline {
Inline::Yes if let Some(file_path) = mod_file_path_from_attr(sess, attrs, &module.dir_path) => {
// For inline modules file path from `#[path]` is actually the directory path
// for historical reasons, so we don't pop the last segment here.
(file_path, DirOwnership::Owned { relative: None })
}
Inline::Yes => {
if let Some(file_path) = mod_file_path_from_attr(sess, attrs, &module.dir_path) {
// For inline modules file path from `#[path]` is actually the directory path
// for historical reasons, so we don't pop the last segment here.
return (file_path, DirOwnership::Owned { relative: None });
}
// We have to push on the current module name in the case of relative
// paths in order to ensure that any additional module paths from inline
// `mod x { ... }` come after the relative extension.

View File

@ -178,18 +178,19 @@ impl FromInternal<(TreeAndSpacing, &'_ mut Vec<Self>, &mut Rustc<'_>)>
tt!(Punct::new('#', false))
}
Interpolated(nt)
if let Some((name, is_raw)) = ident_name_compatibility_hack(&nt, span, rustc) =>
{
TokenTree::Ident(Ident::new(rustc.sess, name.name, is_raw, name.span))
}
Interpolated(nt) => {
if let Some((name, is_raw)) = ident_name_compatibility_hack(&nt, span, rustc) {
TokenTree::Ident(Ident::new(rustc.sess, name.name, is_raw, name.span))
} else {
let stream = nt_to_tokenstream(&nt, rustc.sess, CanSynthesizeMissingTokens::No);
TokenTree::Group(Group {
delimiter: Delimiter::None,
stream,
span: DelimSpan::from_single(span),
flatten: crate::base::pretty_printing_compatibility_hack(&nt, rustc.sess),
})
}
let stream = nt_to_tokenstream(&nt, rustc.sess, CanSynthesizeMissingTokens::No);
TokenTree::Group(Group {
delimiter: Delimiter::None,
stream,
span: DelimSpan::from_single(span),
flatten: crate::base::pretty_printing_compatibility_hack(&nt, rustc.sess),
})
}
OpenDelim(..) | CloseDelim(..) => unreachable!(),

View File

@ -31,6 +31,7 @@
#![feature(box_patterns)]
#![feature(core_intrinsics)]
#![feature(discriminant_kind)]
#![feature(if_let_guard)]
#![feature(never_type)]
#![feature(extern_types)]
#![feature(new_uninit)]
@ -52,6 +53,7 @@
#![feature(try_reserve)]
#![feature(try_reserve_kind)]
#![feature(nonzero_ops)]
#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
#![recursion_limit = "512"]
#[macro_use]

View File

@ -1664,13 +1664,10 @@ impl Debug for Statement<'_> {
AscribeUserType(box (ref place, ref c_ty), ref variance) => {
write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty)
}
Coverage(box ref coverage) => {
if let Some(rgn) = &coverage.code_region {
write!(fmt, "Coverage::{:?} for {:?}", coverage.kind, rgn)
} else {
write!(fmt, "Coverage::{:?}", coverage.kind)
}
Coverage(box self::Coverage { ref kind, code_region: Some(ref rgn) }) => {
write!(fmt, "Coverage::{:?} for {:?}", kind, rgn)
}
Coverage(box ref coverage) => write!(fmt, "Coverage::{:?}", coverage.kind),
CopyNonOverlapping(box crate::mir::CopyNonOverlapping {
ref src,
ref dst,

View File

@ -587,14 +587,12 @@ macro_rules! make_mir_visitor {
InlineAsmOperand::In { value, .. } => {
self.visit_operand(value, location);
}
InlineAsmOperand::Out { place, .. } => {
if let Some(place) = place {
self.visit_place(
place,
PlaceContext::MutatingUse(MutatingUseContext::Store),
location,
);
}
InlineAsmOperand::Out { place: Some(place), .. } => {
self.visit_place(
place,
PlaceContext::MutatingUse(MutatingUseContext::Store),
location,
);
}
InlineAsmOperand::InOut { in_value, out_place, .. } => {
self.visit_operand(in_value, location);
@ -610,7 +608,8 @@ macro_rules! make_mir_visitor {
| InlineAsmOperand::SymFn { value } => {
self.visit_constant(value, location);
}
InlineAsmOperand::SymStatic { def_id: _ } => {}
InlineAsmOperand::Out { place: None, .. }
| InlineAsmOperand::SymStatic { def_id: _ } => {}
}
}
}

View File

@ -14,7 +14,7 @@ use rustc_hir::def::CtorKind;
use rustc_hir::def_id::DefId;
use rustc_hir::RangeEnd;
use rustc_index::newtype_index;
use rustc_index::vec::{Idx, IndexVec};
use rustc_index::vec::IndexVec;
use rustc_middle::infer::canonical::Canonical;
use rustc_middle::middle::region;
use rustc_middle::mir::{
@ -716,17 +716,9 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
PatKind::Variant { adt_def, variant_index, .. } => {
Some(&adt_def.variants[variant_index])
}
_ => {
if let ty::Adt(adt, _) = self.ty.kind() {
if !adt.is_enum() {
Some(&adt.variants[VariantIdx::new(0)])
} else {
None
}
} else {
None
}
}
_ => self.ty.ty_adt_def().and_then(|adt| {
if !adt.is_enum() { Some(adt.non_enum_variant()) } else { None }
}),
};
if let Some(variant) = variant {

View File

@ -279,13 +279,10 @@ impl<'tcx> ty::TyS<'tcx> {
}
ty::FnDef(..) => "fn item".into(),
ty::FnPtr(_) => "fn pointer".into(),
ty::Dynamic(ref inner, ..) => {
if let Some(principal) = inner.principal() {
format!("trait object `dyn {}`", tcx.def_path_str(principal.def_id())).into()
} else {
"trait object".into()
}
ty::Dynamic(ref inner, ..) if let Some(principal) = inner.principal() => {
format!("trait object `dyn {}`", tcx.def_path_str(principal.def_id())).into()
}
ty::Dynamic(..) => "trait object".into(),
ty::Closure(..) => "closure".into(),
ty::Generator(def_id, ..) => tcx.generator_kind(def_id).unwrap().descr().into(),
ty::GeneratorWitness(..) => "generator witness".into(),
@ -365,20 +362,19 @@ impl<'tcx> TyCtxt<'tcx> {
// Issue #63167
db.note("distinct uses of `impl Trait` result in different opaque types");
}
(ty::Float(_), ty::Infer(ty::IntVar(_))) => {
(ty::Float(_), ty::Infer(ty::IntVar(_)))
if let Ok(
// Issue #53280
snippet,
) = self.sess.source_map().span_to_snippet(sp)
{
if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') {
db.span_suggestion(
sp,
"use a float literal",
format!("{}.0", snippet),
MachineApplicable,
);
}
) = self.sess.source_map().span_to_snippet(sp) =>
{
if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') {
db.span_suggestion(
sp,
"use a float literal",
format!("{}.0", snippet),
MachineApplicable,
);
}
}
(ty::Param(expected), ty::Param(found)) => {

View File

@ -927,27 +927,29 @@ pub trait PrettyPrinter<'tcx>:
}
match ct.val {
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
if let Some(promoted) = promoted {
p!(print_value_path(def.did, substs));
p!(write("::{:?}", promoted));
} else {
match self.tcx().def_kind(def.did) {
DefKind::Static | DefKind::Const | DefKind::AssocConst => {
p!(print_value_path(def.did, substs))
}
_ => {
if def.is_local() {
let span = self.tcx().def_span(def.did);
if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span)
{
p!(write("{}", snip))
} else {
print_underscore!()
}
ty::ConstKind::Unevaluated(ty::Unevaluated {
def,
substs,
promoted: Some(promoted),
}) => {
p!(print_value_path(def.did, substs));
p!(write("::{:?}", promoted));
}
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: None }) => {
match self.tcx().def_kind(def.did) {
DefKind::Static | DefKind::Const | DefKind::AssocConst => {
p!(print_value_path(def.did, substs))
}
_ => {
if def.is_local() {
let span = self.tcx().def_span(def.did);
if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span) {
p!(write("{}", snip))
} else {
print_underscore!()
}
} else {
print_underscore!()
}
}
}

View File

@ -225,14 +225,12 @@ impl<'tcx> TyCtxt<'tcx> {
}
}
ty::Tuple(tys) => {
if let Some((&last_ty, _)) = tys.split_last() {
ty = last_ty.expect_ty();
} else {
break;
}
ty::Tuple(tys) if let Some((&last_ty, _)) = tys.split_last() => {
ty = last_ty.expect_ty();
}
ty::Tuple(_) => break,
ty::Projection(_) | ty::Opaque(..) => {
let normalized = normalize(ty);
if ty == normalized {

View File

@ -2,8 +2,10 @@
#![feature(array_windows)]
#![feature(crate_visibility_modifier)]
#![feature(if_let_guard)]
#![cfg_attr(bootstrap, feature(bindings_after_at))]
#![feature(box_patterns)]
#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
#![recursion_limit = "256"]
use rustc_ast as ast;
@ -262,20 +264,17 @@ pub fn nt_to_tokenstream(
let tokens = match *nt {
Nonterminal::NtItem(ref item) => prepend_attrs(&item.attrs, item.tokens.as_ref()),
Nonterminal::NtBlock(ref block) => convert_tokens(block.tokens.as_ref()),
Nonterminal::NtStmt(ref stmt) => {
if let ast::StmtKind::Empty = stmt.kind {
let tokens = AttrAnnotatedTokenStream::new(vec![(
tokenstream::AttrAnnotatedTokenTree::Token(Token::new(
TokenKind::Semi,
stmt.span,
)),
Spacing::Alone,
)]);
prepend_attrs(&stmt.attrs(), Some(&LazyTokenStream::new(tokens)))
} else {
prepend_attrs(&stmt.attrs(), stmt.tokens())
}
Nonterminal::NtStmt(ref stmt) if let ast::StmtKind::Empty = stmt.kind => {
let tokens = AttrAnnotatedTokenStream::new(vec![(
tokenstream::AttrAnnotatedTokenTree::Token(Token::new(
TokenKind::Semi,
stmt.span,
)),
Spacing::Alone,
)]);
prepend_attrs(&stmt.attrs(), Some(&LazyTokenStream::new(tokens)))
}
Nonterminal::NtStmt(ref stmt) => prepend_attrs(&stmt.attrs(), stmt.tokens()),
Nonterminal::NtPat(ref pat) => convert_tokens(pat.tokens.as_ref()),
Nonterminal::NtTy(ref ty) => convert_tokens(ty.tokens.as_ref()),
Nonterminal::NtIdent(ident, is_raw) => {

View File

@ -143,15 +143,16 @@ impl<'a> Parser<'a> {
token::NtTy(self.collect_tokens_no_attrs(|this| this.parse_ty())?)
}
// this could be handled like a token, since it is one
NonterminalKind::Ident
if let Some((ident, is_raw)) = get_macro_ident(&self.token) =>
{
self.bump();
token::NtIdent(ident, is_raw)
}
NonterminalKind::Ident => {
if let Some((ident, is_raw)) = get_macro_ident(&self.token) {
self.bump();
token::NtIdent(ident, is_raw)
} else {
let token_str = pprust::token_to_string(&self.token);
let msg = &format!("expected ident, found {}", &token_str);
return Err(self.struct_span_err(self.token.span, msg));
}
let token_str = pprust::token_to_string(&self.token);
let msg = &format!("expected ident, found {}", &token_str);
return Err(self.struct_span_err(self.token.span, msg));
}
NonterminalKind::Path => token::NtPath(
self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?,

View File

@ -493,21 +493,19 @@ impl<'a> Parser<'a> {
}
}
StmtKind::Expr(_) | StmtKind::MacCall(_) => {}
StmtKind::Local(ref mut local) => {
if let Err(e) = self.expect_semi() {
// We might be at the `,` in `let x = foo<bar, baz>;`. Try to recover.
match &mut local.init {
Some(ref mut expr) => {
self.check_mistyped_turbofish_with_multiple_type_params(e, expr)?;
// We found `foo<bar, baz>`, have we fully recovered?
self.expect_semi()?;
}
None => return Err(e),
StmtKind::Local(ref mut local) if let Err(e) = self.expect_semi() => {
// We might be at the `,` in `let x = foo<bar, baz>;`. Try to recover.
match &mut local.init {
Some(ref mut expr) => {
self.check_mistyped_turbofish_with_multiple_type_params(e, expr)?;
// We found `foo<bar, baz>`, have we fully recovered?
self.expect_semi()?;
}
None => return Err(e),
}
eat_semi = false;
}
StmtKind::Empty | StmtKind::Item(_) | StmtKind::Semi(_) => eat_semi = false,
StmtKind::Empty | StmtKind::Item(_) | StmtKind::Local(_) | StmtKind::Semi(_) => eat_semi = false,
}
if eat_semi && self.eat(&token::Semi) {

View File

@ -24,16 +24,15 @@ pub fn check_meta(sess: &ParseSess, attr: &Attribute) {
Some((name, _, template, _)) if name != sym::rustc_dummy => {
check_builtin_attribute(sess, attr, name, template)
}
_ => {
if let MacArgs::Eq(..) = attr.get_normal_item().args {
// All key-value attributes are restricted to meta-item syntax.
parse_meta(sess, attr)
.map_err(|mut err| {
err.emit();
})
.ok();
}
_ if let MacArgs::Eq(..) = attr.get_normal_item().args => {
// All key-value attributes are restricted to meta-item syntax.
parse_meta(sess, attr)
.map_err(|mut err| {
err.emit();
})
.ok();
}
_ => {}
}
}

View File

@ -1,5 +1,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(if_let_guard)]
#![feature(nll)]
#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
#![recursion_limit = "256"]
mod dump_visitor;
@ -326,54 +328,53 @@ impl<'tcx> SaveContext<'tcx> {
attributes: lower_attributes(attrs.to_vec(), self),
}))
}
hir::ItemKind::Impl(hir::Impl { ref of_trait, ref self_ty, ref items, .. }) => {
if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = self_ty.kind {
// Common case impl for a struct or something basic.
if generated_code(path.span) {
return None;
}
let sub_span = path.segments.last().unwrap().ident.span;
filter!(self.span_utils, sub_span);
let impl_id = self.next_impl_id();
let span = self.span_from_span(sub_span);
let type_data = self.lookup_def_id(self_ty.hir_id);
type_data.map(|type_data| {
Data::RelationData(
Relation {
kind: RelationKind::Impl { id: impl_id },
span: span.clone(),
from: id_from_def_id(type_data),
to: of_trait
.as_ref()
.and_then(|t| self.lookup_def_id(t.hir_ref_id))
.map(id_from_def_id)
.unwrap_or_else(null_id),
},
Impl {
id: impl_id,
kind: match *of_trait {
Some(_) => ImplKind::Direct,
None => ImplKind::Inherent,
},
span,
value: String::new(),
parent: None,
children: items
.iter()
.map(|i| id_from_def_id(i.id.def_id.to_def_id()))
.collect(),
docs: String::new(),
sig: None,
attributes: vec![],
},
)
})
} else {
None
hir::ItemKind::Impl(hir::Impl { ref of_trait, ref self_ty, ref items, .. })
if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = self_ty.kind =>
{
// Common case impl for a struct or something basic.
if generated_code(path.span) {
return None;
}
let sub_span = path.segments.last().unwrap().ident.span;
filter!(self.span_utils, sub_span);
let impl_id = self.next_impl_id();
let span = self.span_from_span(sub_span);
let type_data = self.lookup_def_id(self_ty.hir_id);
type_data.map(|type_data| {
Data::RelationData(
Relation {
kind: RelationKind::Impl { id: impl_id },
span: span.clone(),
from: id_from_def_id(type_data),
to: of_trait
.as_ref()
.and_then(|t| self.lookup_def_id(t.hir_ref_id))
.map(id_from_def_id)
.unwrap_or_else(null_id),
},
Impl {
id: impl_id,
kind: match *of_trait {
Some(_) => ImplKind::Direct,
None => ImplKind::Inherent,
},
span,
value: String::new(),
parent: None,
children: items
.iter()
.map(|i| id_from_def_id(i.id.def_id.to_def_id()))
.collect(),
docs: String::new(),
sig: None,
attributes: vec![],
},
)
})
}
hir::ItemKind::Impl(_) => None,
_ => {
// FIXME
bug!();

View File

@ -16,10 +16,12 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(array_windows)]
#![feature(crate_visibility_modifier)]
#![feature(if_let_guard)]
#![feature(negative_impls)]
#![feature(nll)]
#![feature(min_specialization)]
#![feature(thread_local_const_init)]
#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
#[macro_use]
extern crate rustc_macros;

View File

@ -982,15 +982,13 @@ impl SourceMap {
None
}
pub fn ensure_source_file_source_present(&self, source_file: Lrc<SourceFile>) -> bool {
source_file.add_external_src(|| match source_file.name {
FileName::Real(ref name) => {
if let Some(local_path) = name.local_path() {
source_file.add_external_src(|| {
match source_file.name {
FileName::Real(ref name) if let Some(local_path) = name.local_path() => {
self.file_loader.read_file(local_path).ok()
} else {
None
}
_ => None,
}
_ => None,
})
}
@ -1033,22 +1031,19 @@ impl FilePathMapping {
fn map_filename_prefix(&self, file: &FileName) -> (FileName, bool) {
match file {
FileName::Real(realfile) => {
if let RealFileName::LocalPath(local_path) = realfile {
let (mapped_path, mapped) = self.map_prefix(local_path.to_path_buf());
let realfile = if mapped {
RealFileName::Remapped {
local_path: Some(local_path.clone()),
virtual_name: mapped_path,
}
} else {
realfile.clone()
};
(FileName::Real(realfile), mapped)
FileName::Real(realfile) if let RealFileName::LocalPath(local_path) = realfile => {
let (mapped_path, mapped) = self.map_prefix(local_path.to_path_buf());
let realfile = if mapped {
RealFileName::Remapped {
local_path: Some(local_path.clone()),
virtual_name: mapped_path,
}
} else {
unreachable!("attempted to remap an already remapped filename");
}
realfile.clone()
};
(FileName::Real(realfile), mapped)
}
FileName::Real(_) => unreachable!("attempted to remap an already remapped filename"),
other => (other.clone(), false),
}
}

View File

@ -2380,12 +2380,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if let Some(i) = (param.index as usize).checked_sub(generics.parent_count) {
// Our own parameters are the resolved lifetimes.
match param.kind {
GenericParamDefKind::Lifetime => {
if let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] {
self.ast_region_to_region(lifetime, None).into()
} else {
bug!()
}
GenericParamDefKind::Lifetime
if let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] =>
{
self.ast_region_to_region(lifetime, None).into()
}
_ => bug!(),
}

View File

@ -2164,14 +2164,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::InlineAsmOperand::In { expr, .. } => {
self.check_expr_asm_operand(expr, true);
}
hir::InlineAsmOperand::Out { expr, .. } => {
if let Some(expr) = expr {
self.check_expr_asm_operand(expr, false);
}
}
hir::InlineAsmOperand::InOut { expr, .. } => {
hir::InlineAsmOperand::Out { expr: Some(expr), .. }
| hir::InlineAsmOperand::InOut { expr, .. } => {
self.check_expr_asm_operand(expr, false);
}
hir::InlineAsmOperand::Out { expr: None, .. } => {}
hir::InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
self.check_expr_asm_operand(in_expr, true);
if let Some(out_expr) = out_expr {

View File

@ -1199,12 +1199,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut user_self_ty = None;
let mut is_alias_variant_ctor = false;
match res {
Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
if let Some(self_ty) = self_ty {
let adt_def = self_ty.ty_adt_def().unwrap();
user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
is_alias_variant_ctor = true;
}
Res::Def(DefKind::Ctor(CtorOf::Variant, _), _)
if let Some(self_ty) = self_ty =>
{
let adt_def = self_ty.ty_adt_def().unwrap();
user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
is_alias_variant_ctor = true;
}
Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
let container = tcx.associated_item(def_id).container;

View File

@ -616,32 +616,30 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
let lang_items = self.tcx.lang_items();
match *self_ty.value.value.kind() {
ty::Dynamic(ref data, ..) => {
if let Some(p) = data.principal() {
// Subtle: we can't use `instantiate_query_response` here: using it will
// commit to all of the type equalities assumed by inference going through
// autoderef (see the `method-probe-no-guessing` test).
//
// However, in this code, it is OK if we end up with an object type that is
// "more general" than the object type that we are evaluating. For *every*
// object type `MY_OBJECT`, a function call that goes through a trait-ref
// of the form `<MY_OBJECT as SuperTraitOf(MY_OBJECT)>::func` is a valid
// `ObjectCandidate`, and it should be discoverable "exactly" through one
// of the iterations in the autoderef loop, so there is no problem with it
// being discoverable in another one of these iterations.
//
// Using `instantiate_canonical_with_fresh_inference_vars` on our
// `Canonical<QueryResponse<Ty<'tcx>>>` and then *throwing away* the
// `CanonicalVarValues` will exactly give us such a generalization - it
// will still match the original object type, but it won't pollute our
// type variables in any form, so just do that!
let (QueryResponse { value: generalized_self_ty, .. }, _ignored_var_values) =
self.fcx
.instantiate_canonical_with_fresh_inference_vars(self.span, &self_ty);
ty::Dynamic(ref data, ..) if let Some(p) = data.principal() => {
// Subtle: we can't use `instantiate_query_response` here: using it will
// commit to all of the type equalities assumed by inference going through
// autoderef (see the `method-probe-no-guessing` test).
//
// However, in this code, it is OK if we end up with an object type that is
// "more general" than the object type that we are evaluating. For *every*
// object type `MY_OBJECT`, a function call that goes through a trait-ref
// of the form `<MY_OBJECT as SuperTraitOf(MY_OBJECT)>::func` is a valid
// `ObjectCandidate`, and it should be discoverable "exactly" through one
// of the iterations in the autoderef loop, so there is no problem with it
// being discoverable in another one of these iterations.
//
// Using `instantiate_canonical_with_fresh_inference_vars` on our
// `Canonical<QueryResponse<Ty<'tcx>>>` and then *throwing away* the
// `CanonicalVarValues` will exactly give us such a generalization - it
// will still match the original object type, but it won't pollute our
// type variables in any form, so just do that!
let (QueryResponse { value: generalized_self_ty, .. }, _ignored_var_values) =
self.fcx
.instantiate_canonical_with_fresh_inference_vars(self.span, &self_ty);
self.assemble_inherent_candidates_from_object(generalized_self_ty);
self.assemble_inherent_impl_candidates_for_type(p.def_id());
}
self.assemble_inherent_candidates_from_object(generalized_self_ty);
self.assemble_inherent_impl_candidates_for_type(p.def_id());
}
ty::Adt(def, _) => {
self.assemble_inherent_impl_candidates_for_type(def.did);

View File

@ -627,15 +627,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let binding_parent = tcx.hir().get(binding_parent_id);
debug!("inner {:?} pat {:?} parent {:?}", inner, pat, binding_parent);
match binding_parent {
hir::Node::Param(hir::Param { span, .. }) => {
if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
err.span_suggestion(
*span,
&format!("did you mean `{}`", snippet),
format!(" &{}", expected),
Applicability::MachineApplicable,
);
}
hir::Node::Param(hir::Param { span, .. })
if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) =>
{
err.span_suggestion(
*span,
&format!("did you mean `{}`", snippet),
format!(" &{}", expected),
Applicability::MachineApplicable,
);
}
hir::Node::Arm(_) | hir::Node::Pat(_) => {
// rely on match ergonomics or it might be nested `&&pat`
@ -1293,13 +1293,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(Some(mut err), None) => {
err.emit();
}
(None, None) => {
if let Some(mut err) =
self.error_tuple_variant_index_shorthand(variant, pat, fields)
{
err.emit();
}
(None, None) if let Some(mut err) =
self.error_tuple_variant_index_shorthand(variant, pat, fields) =>
{
err.emit();
}
(None, None) => {}
}
no_field_errors
}

View File

@ -1049,26 +1049,24 @@ fn check_opaque_types<'fcx, 'tcx>(
let arg_is_param = match arg.unpack() {
GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
GenericArgKind::Lifetime(region) => {
if let ty::ReStatic = region {
tcx.sess
.struct_span_err(
span,
"non-defining opaque type use in defining scope",
)
.span_label(
tcx.def_span(generics.param_at(i, tcx).def_id),
"cannot use static lifetime; use a bound lifetime \
instead or remove the lifetime parameter from the \
opaque type",
)
.emit();
continue;
}
true
GenericArgKind::Lifetime(region) if let ty::ReStatic = region => {
tcx.sess
.struct_span_err(
span,
"non-defining opaque type use in defining scope",
)
.span_label(
tcx.def_span(generics.param_at(i, tcx).def_id),
"cannot use static lifetime; use a bound lifetime \
instead or remove the lifetime parameter from the \
opaque type",
)
.emit();
continue;
}
GenericArgKind::Lifetime(_) => true,
GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)),
};

View File

@ -175,10 +175,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
}
}
}
hir::ExprKind::AssignOp(..) => {
if let Some(a) = typeck_results.adjustments_mut().get_mut(lhs.hir_id) {
a.pop();
}
hir::ExprKind::AssignOp(..)
if let Some(a) = typeck_results.adjustments_mut().get_mut(lhs.hir_id) =>
{
a.pop();
}
_ => {}
}

View File

@ -446,13 +446,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
}
}
Node::AnonConst(_) => {
if let Some(param) = tcx.opt_const_param_of(def_id) {
// We defer to `type_of` of the corresponding parameter
// for generic arguments.
return tcx.type_of(param);
}
Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => {
// We defer to `type_of` of the corresponding parameter
// for generic arguments.
tcx.type_of(param)
}
Node::AnonConst(_) => {
let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
match parent_node {
Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. })

View File

@ -334,12 +334,8 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
match op {
hir::InlineAsmOperand::In { expr, .. }
| hir::InlineAsmOperand::Sym { expr, .. } => self.consume_expr(expr),
hir::InlineAsmOperand::Out { expr, .. } => {
if let Some(expr) = expr {
self.mutate_expr(expr);
}
}
hir::InlineAsmOperand::InOut { expr, .. } => {
hir::InlineAsmOperand::Out { expr: Some(expr), .. }
| hir::InlineAsmOperand::InOut { expr, .. } => {
self.mutate_expr(expr);
}
hir::InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
@ -348,7 +344,8 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
self.mutate_expr(out_expr);
}
}
hir::InlineAsmOperand::Const { .. } => {}
hir::InlineAsmOperand::Out { expr: None, .. }
| hir::InlineAsmOperand::Const { .. } => {}
}
}
}

View File

@ -60,6 +60,7 @@ This API is completely unstable and subject to change.
#![feature(bool_to_option)]
#![feature(crate_visibility_modifier)]
#![feature(format_args_capture)]
#![feature(if_let_guard)]
#![feature(in_band_lifetimes)]
#![feature(is_sorted)]
#![feature(iter_zip)]
@ -68,6 +69,7 @@ This API is completely unstable and subject to change.
#![feature(never_type)]
#![feature(slice_partition_dedup)]
#![feature(control_flow_enum)]
#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
#![recursion_limit = "256"]
#[macro_use]

View File

@ -69,6 +69,7 @@
#![warn(missing_debug_implementations)]
#![warn(missing_docs)]
#![allow(explicit_outlives_requirements)]
#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
//
// Library features for const fns:
#![feature(const_align_of_val)]
@ -134,6 +135,7 @@
#![feature(exhaustive_patterns)]
#![feature(extern_types)]
#![feature(fundamental)]
#![feature(if_let_guard)]
#![feature(intra_doc_pointers)]
#![feature(intrinsics)]
#![feature(lang_items)]

View File

@ -236,13 +236,8 @@ pub fn dec2flt<F: RawFloat>(s: &str) -> Result<F, ParseFloatError> {
let num = match parse_number(s, negative) {
Some(r) => r,
None => {
if let Some(value) = parse_inf_nan(s, negative) {
return Ok(value);
} else {
return Err(pfe_invalid());
}
}
None if let Some(value) = parse_inf_nan(s, negative) => return Ok(value),
None => return Err(pfe_invalid()),
};
if let Some(value) = num.try_fast_path::<F>() {
return Ok(value);