mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 01:34:21 +00:00
Auto merge of #71231 - cuviper:rustc_or_patterns, r=Mark-Simulacrum
Dogfood more or_patterns in the compiler Another step toward the stabilization of `or_patterns`... cc #54883 @Centril r? @Mark-Simulacrum
This commit is contained in:
commit
ad48d52a74
@ -10,6 +10,7 @@
|
||||
test(attr(deny(warnings)))
|
||||
)]
|
||||
#![feature(nll)]
|
||||
#![feature(or_patterns)]
|
||||
#![feature(rustc_private)]
|
||||
#![feature(unicode_internals)]
|
||||
#![feature(bool_to_option)]
|
||||
@ -482,7 +483,7 @@ impl<'a> Parser<'a> {
|
||||
// fill character
|
||||
if let Some(&(_, c)) = self.cur.peek() {
|
||||
match self.cur.clone().nth(1) {
|
||||
Some((_, '>')) | Some((_, '<')) | Some((_, '^')) => {
|
||||
Some((_, '>' | '<' | '^')) => {
|
||||
spec.fill = Some(c);
|
||||
self.cur.next();
|
||||
}
|
||||
|
@ -744,7 +744,7 @@ impl<S: Semantics> Float for IeeeFloat<S> {
|
||||
Status::OK
|
||||
}
|
||||
|
||||
(Category::Zero, _) | (_, Category::NaN) | (_, Category::Infinity) => {
|
||||
(Category::Zero, _) | (_, Category::NaN | Category::Infinity) => {
|
||||
self = rhs;
|
||||
Status::OK
|
||||
}
|
||||
@ -954,7 +954,7 @@ impl<S: Semantics> Float for IeeeFloat<S> {
|
||||
Status::INVALID_OP.and(Self::NAN)
|
||||
}
|
||||
|
||||
(Category::Infinity, _) | (Category::Zero, _) => Status::OK.and(self),
|
||||
(Category::Infinity | Category::Zero, _) => Status::OK.and(self),
|
||||
|
||||
(Category::Normal, Category::Infinity) => {
|
||||
self.category = Category::Zero;
|
||||
@ -989,8 +989,7 @@ impl<S: Semantics> Float for IeeeFloat<S> {
|
||||
fn c_fmod(mut self, rhs: Self) -> StatusAnd<Self> {
|
||||
match (self.category, rhs.category) {
|
||||
(Category::NaN, _)
|
||||
| (Category::Zero, Category::Infinity)
|
||||
| (Category::Zero, Category::Normal)
|
||||
| (Category::Zero, Category::Infinity | Category::Normal)
|
||||
| (Category::Normal, Category::Infinity) => Status::OK.and(self),
|
||||
|
||||
(_, Category::NaN) => {
|
||||
|
@ -34,6 +34,7 @@
|
||||
#![no_std]
|
||||
#![forbid(unsafe_code)]
|
||||
#![feature(nll)]
|
||||
#![feature(or_patterns)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate alloc;
|
||||
|
@ -186,9 +186,7 @@ where
|
||||
Status::OK.and(self)
|
||||
}
|
||||
|
||||
(Category::Zero, _) | (_, Category::NaN) | (_, Category::Infinity) => {
|
||||
Status::OK.and(rhs)
|
||||
}
|
||||
(Category::Zero, _) | (_, Category::NaN | Category::Infinity) => Status::OK.and(rhs),
|
||||
|
||||
(Category::Normal, Category::Normal) => {
|
||||
let mut status = Status::OK;
|
||||
@ -288,9 +286,9 @@ where
|
||||
Status::OK.and(Self::NAN)
|
||||
}
|
||||
|
||||
(Category::Zero, _) | (Category::Infinity, _) => Status::OK.and(self),
|
||||
(Category::Zero | Category::Infinity, _) => Status::OK.and(self),
|
||||
|
||||
(_, Category::Zero) | (_, Category::Infinity) => Status::OK.and(rhs),
|
||||
(_, Category::Zero | Category::Infinity) => Status::OK.and(rhs),
|
||||
|
||||
(Category::Normal, Category::Normal) => {
|
||||
let mut status = Status::OK;
|
||||
|
@ -1569,8 +1569,7 @@ impl LitKind {
|
||||
pub fn is_suffixed(&self) -> bool {
|
||||
match *self {
|
||||
// suffixed variants
|
||||
LitKind::Int(_, LitIntType::Signed(..))
|
||||
| LitKind::Int(_, LitIntType::Unsigned(..))
|
||||
LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
|
||||
| LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
|
||||
// unsuffixed variants
|
||||
LitKind::Str(..)
|
||||
|
@ -442,8 +442,10 @@ impl MetaItem {
|
||||
{
|
||||
// FIXME: Share code with `parse_path`.
|
||||
let path = match tokens.next().map(TokenTree::uninterpolate) {
|
||||
Some(TokenTree::Token(Token { kind: kind @ token::Ident(..), span }))
|
||||
| Some(TokenTree::Token(Token { kind: kind @ token::ModSep, span })) => 'arm: {
|
||||
Some(TokenTree::Token(Token {
|
||||
kind: kind @ (token::Ident(..) | token::ModSep),
|
||||
span,
|
||||
})) => 'arm: {
|
||||
let mut segments = if let token::Ident(name, _) = kind {
|
||||
if let Some(TokenTree::Token(Token { kind: token::ModSep, .. })) = tokens.peek()
|
||||
{
|
||||
|
@ -14,6 +14,7 @@
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(label_break_value)]
|
||||
#![feature(nll)]
|
||||
#![feature(or_patterns)]
|
||||
#![feature(try_trait)]
|
||||
#![feature(unicode_internals)]
|
||||
#![recursion_limit = "256"]
|
||||
|
@ -226,11 +226,11 @@ pub fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec<Comme
|
||||
rustc_lexer::TokenKind::BlockComment { terminated: _ } => {
|
||||
if !is_block_doc_comment(token_text) {
|
||||
let code_to_the_right = match text[pos + token.len..].chars().next() {
|
||||
Some('\r') | Some('\n') => false,
|
||||
Some('\r' | '\n') => false,
|
||||
_ => true,
|
||||
};
|
||||
let style = match (code_to_the_left, code_to_the_right) {
|
||||
(true, true) | (false, true) => Mixed,
|
||||
(_, true) => Mixed,
|
||||
(false, false) => Isolated,
|
||||
(true, false) => Trailing,
|
||||
};
|
||||
|
@ -1239,16 +1239,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let bounds =
|
||||
this.arena.alloc_from_iter(bounds.iter().filter_map(
|
||||
|bound| match *bound {
|
||||
GenericBound::Trait(ref ty, TraitBoundModifier::None)
|
||||
| GenericBound::Trait(ref ty, TraitBoundModifier::MaybeConst) => {
|
||||
Some(this.lower_poly_trait_ref(ty, itctx.reborrow()))
|
||||
}
|
||||
GenericBound::Trait(
|
||||
ref ty,
|
||||
TraitBoundModifier::None | TraitBoundModifier::MaybeConst,
|
||||
) => Some(this.lower_poly_trait_ref(ty, itctx.reborrow())),
|
||||
// `?const ?Bound` will cause an error during AST validation
|
||||
// anyways, so treat it like `?Bound` as compilation proceeds.
|
||||
GenericBound::Trait(_, TraitBoundModifier::Maybe)
|
||||
| GenericBound::Trait(_, TraitBoundModifier::MaybeConstMaybe) => {
|
||||
None
|
||||
}
|
||||
GenericBound::Trait(
|
||||
_,
|
||||
TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe,
|
||||
) => None,
|
||||
GenericBound::Outlives(ref lifetime) => {
|
||||
if lifetime_bound.is_none() {
|
||||
lifetime_bound = Some(this.lower_lifetime(lifetime));
|
||||
@ -1740,8 +1740,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
c_variadic,
|
||||
implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
|
||||
let is_mutable_pat = match arg.pat.kind {
|
||||
PatKind::Ident(BindingMode::ByValue(mt), _, _)
|
||||
| PatKind::Ident(BindingMode::ByRef(mt), _, _) => mt == Mutability::Mut,
|
||||
PatKind::Ident(BindingMode::ByValue(mt) | BindingMode::ByRef(mt), _, _) => {
|
||||
mt == Mutability::Mut
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
@ -2468,7 +2469,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
hir::QPath::Resolved(None, path) => {
|
||||
// Turn trait object paths into `TyKind::TraitObject` instead.
|
||||
match path.res {
|
||||
Res::Def(DefKind::Trait, _) | Res::Def(DefKind::TraitAlias, _) => {
|
||||
Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
|
||||
let principal = hir::PolyTraitRef {
|
||||
bound_generic_params: &[],
|
||||
trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
|
||||
|
@ -194,7 +194,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
) -> hir::PatKind<'hir> {
|
||||
match self.resolver.get_partial_res(p.id).map(|d| d.base_res()) {
|
||||
// `None` can occur in body-less function signatures
|
||||
res @ None | res @ Some(Res::Local(_)) => {
|
||||
res @ (None | Some(Res::Local(_))) => {
|
||||
let canonical_id = match res {
|
||||
Some(Res::Local(id)) => id,
|
||||
_ => p.id,
|
||||
|
@ -1,5 +1,6 @@
|
||||
#![feature(bool_to_option)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(or_patterns)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
mod helpers;
|
||||
|
@ -1735,8 +1735,9 @@ impl<'a> State<'a> {
|
||||
// These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is
|
||||
// the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead
|
||||
// of `(x as i32) < ...`. We need to convince it _not_ to do that.
|
||||
(&ast::ExprKind::Cast { .. }, ast::BinOpKind::Lt)
|
||||
| (&ast::ExprKind::Cast { .. }, ast::BinOpKind::Shl) => parser::PREC_FORCE_PAREN,
|
||||
(&ast::ExprKind::Cast { .. }, ast::BinOpKind::Lt | ast::BinOpKind::Shl) => {
|
||||
parser::PREC_FORCE_PAREN
|
||||
}
|
||||
// We are given `(let _ = a) OP b`.
|
||||
//
|
||||
// - When `OP <= LAnd` we should print `let _ = a OP b` to avoid redundant parens
|
||||
|
@ -26,9 +26,12 @@ pub fn expand_concat(
|
||||
ast::LitKind::Char(c) => {
|
||||
accumulator.push(c);
|
||||
}
|
||||
ast::LitKind::Int(i, ast::LitIntType::Unsigned(_))
|
||||
| ast::LitKind::Int(i, ast::LitIntType::Signed(_))
|
||||
| ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) => {
|
||||
ast::LitKind::Int(
|
||||
i,
|
||||
ast::LitIntType::Unsigned(_)
|
||||
| ast::LitIntType::Signed(_)
|
||||
| ast::LitIntType::Unsuffixed,
|
||||
) => {
|
||||
accumulator.push_str(&i.to_string());
|
||||
}
|
||||
ast::LitKind::Bool(b) => {
|
||||
|
@ -918,24 +918,15 @@ pub fn expand_preparsed_format_args(
|
||||
skips.push(*next_pos);
|
||||
let _ = s.next();
|
||||
}
|
||||
('\\', Some((next_pos, '\n')))
|
||||
| ('\\', Some((next_pos, 'n')))
|
||||
| ('\\', Some((next_pos, 't')))
|
||||
if eat_ws =>
|
||||
{
|
||||
('\\', Some((next_pos, '\n' | 'n' | 't'))) if eat_ws => {
|
||||
skips.push(pos);
|
||||
skips.push(*next_pos);
|
||||
let _ = s.next();
|
||||
}
|
||||
(' ', _) | ('\n', _) | ('\t', _) if eat_ws => {
|
||||
(' ' | '\n' | '\t', _) if eat_ws => {
|
||||
skips.push(pos);
|
||||
}
|
||||
('\\', Some((next_pos, 'n')))
|
||||
| ('\\', Some((next_pos, 't')))
|
||||
| ('\\', Some((next_pos, '0')))
|
||||
| ('\\', Some((next_pos, '\\')))
|
||||
| ('\\', Some((next_pos, '\'')))
|
||||
| ('\\', Some((next_pos, '\"'))) => {
|
||||
('\\', Some((next_pos, 'n' | 't' | '0' | '\\' | '\'' | '\"'))) => {
|
||||
skips.push(*next_pos);
|
||||
let _ = s.next();
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ pub mod printf {
|
||||
};
|
||||
|
||||
let alt = match type_ {
|
||||
Some("x") | Some("X") => alt,
|
||||
Some("x" | "X") => alt,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
@ -506,7 +506,7 @@ pub mod printf {
|
||||
move_to!(next1);
|
||||
}
|
||||
|
||||
('h', _) | ('l', _) | ('L', _) | ('z', _) | ('j', _) | ('t', _) | ('q', _) => {
|
||||
('h' | 'l' | 'L' | 'z' | 'j' | 't' | 'q', _) => {
|
||||
state = Type;
|
||||
length = Some(at.slice_between(next).unwrap());
|
||||
move_to!(next);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(nll)]
|
||||
#![feature(or_patterns)]
|
||||
#![feature(proc_macro_internals)]
|
||||
#![feature(proc_macro_quote)]
|
||||
|
||||
|
@ -86,8 +86,7 @@ fn parse_inline_asm<'a>(
|
||||
let first_colon = tts
|
||||
.trees()
|
||||
.position(|tt| match tt {
|
||||
tokenstream::TokenTree::Token(Token { kind: token::Colon, .. })
|
||||
| tokenstream::TokenTree::Token(Token { kind: token::ModSep, .. }) => true,
|
||||
tokenstream::TokenTree::Token(Token { kind: token::Colon | token::ModSep, .. }) => true,
|
||||
_ => false,
|
||||
})
|
||||
.unwrap_or(tts.len());
|
||||
|
@ -124,7 +124,7 @@ fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
|
||||
// sanitizer and thread sanitizer. With asan we're already protected from
|
||||
// stack overflow anyway so we don't really need stack probes regardless.
|
||||
match cx.sess().opts.debugging_opts.sanitizer {
|
||||
Some(Sanitizer::Address) | Some(Sanitizer::Thread) => return,
|
||||
Some(Sanitizer::Address | Sanitizer::Thread) => return,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
@ -310,7 +310,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
let new_kind = match ty.kind {
|
||||
Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.ptr_width)),
|
||||
Uint(t @ Usize) => Uint(t.normalize(self.tcx.sess.target.ptr_width)),
|
||||
ref t @ Uint(_) | ref t @ Int(_) => t.clone(),
|
||||
ref t @ (Uint(_) | Int(_)) => t.clone(),
|
||||
_ => panic!("tried to get overflow intrinsic for op applied to non-int type"),
|
||||
};
|
||||
|
||||
@ -1247,7 +1247,7 @@ impl Builder<'a, 'll, 'tcx> {
|
||||
let emit = match opts.debugging_opts.sanitizer {
|
||||
// Some sanitizer use lifetime intrinsics. When they are in use,
|
||||
// emit lifetime intrinsics regardless of optimization level.
|
||||
Some(Sanitizer::Address) | Some(Sanitizer::Memory) => true,
|
||||
Some(Sanitizer::Address | Sanitizer::Memory) => true,
|
||||
_ => opts.optimize != config::OptLevel::No,
|
||||
};
|
||||
if !emit {
|
||||
|
@ -11,6 +11,7 @@
|
||||
#![feature(extern_types)]
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![feature(nll)]
|
||||
#![feature(or_patterns)]
|
||||
#![feature(trusted_len)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
|
@ -262,7 +262,7 @@ pub fn each_linked_rlib(
|
||||
};
|
||||
for &(cnum, ref path) in crates {
|
||||
match fmts.get(cnum.as_usize() - 1) {
|
||||
Some(&Linkage::NotLinked) | Some(&Linkage::IncludedFromDylib) => continue,
|
||||
Some(&Linkage::NotLinked | &Linkage::IncludedFromDylib) => continue,
|
||||
Some(_) => {}
|
||||
None => return Err("could not find formats for rlibs".to_string()),
|
||||
}
|
||||
|
@ -86,8 +86,10 @@ fn reachable_non_generics_provider(
|
||||
}
|
||||
|
||||
// Only consider nodes that actually have exported symbols.
|
||||
Node::Item(&hir::Item { kind: hir::ItemKind::Static(..), .. })
|
||||
| Node::Item(&hir::Item { kind: hir::ItemKind::Fn(..), .. })
|
||||
Node::Item(&hir::Item {
|
||||
kind: hir::ItemKind::Static(..) | hir::ItemKind::Fn(..),
|
||||
..
|
||||
})
|
||||
| Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => {
|
||||
let def_id = tcx.hir().local_def_id(hir_id);
|
||||
let generics = tcx.generics_of(def_id);
|
||||
|
@ -182,8 +182,7 @@ pub fn unsize_thin_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
) -> (Bx::Value, Bx::Value) {
|
||||
debug!("unsize_thin_ptr: {:?} => {:?}", src_ty, dst_ty);
|
||||
match (&src_ty.kind, &dst_ty.kind) {
|
||||
(&ty::Ref(_, a, _), &ty::Ref(_, b, _))
|
||||
| (&ty::Ref(_, a, _), &ty::RawPtr(ty::TypeAndMut { ty: b, .. }))
|
||||
(&ty::Ref(_, a, _), &ty::Ref(_, b, _) | &ty::RawPtr(ty::TypeAndMut { ty: b, .. }))
|
||||
| (&ty::RawPtr(ty::TypeAndMut { ty: a, .. }), &ty::RawPtr(ty::TypeAndMut { ty: b, .. })) => {
|
||||
assert!(bx.cx().type_is_sized(a));
|
||||
let ptr_ty = bx.cx().type_ptr_to(bx.cx().backend_type(bx.cx().layout_of(b)));
|
||||
@ -232,9 +231,7 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
let src_ty = src.layout.ty;
|
||||
let dst_ty = dst.layout.ty;
|
||||
match (&src_ty.kind, &dst_ty.kind) {
|
||||
(&ty::Ref(..), &ty::Ref(..))
|
||||
| (&ty::Ref(..), &ty::RawPtr(..))
|
||||
| (&ty::RawPtr(..), &ty::RawPtr(..)) => {
|
||||
(&ty::Ref(..), &ty::Ref(..) | &ty::RawPtr(..)) | (&ty::RawPtr(..), &ty::RawPtr(..)) => {
|
||||
let (base, info) = match bx.load_operand(src).val {
|
||||
OperandValue::Pair(base, info) => {
|
||||
// fat-ptr to fat-ptr unsize preserves the vtable
|
||||
|
@ -4,6 +4,7 @@
|
||||
#![feature(try_blocks)]
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![feature(nll)]
|
||||
#![feature(or_patterns)]
|
||||
#![feature(trusted_len)]
|
||||
#![feature(associated_type_bounds)]
|
||||
#![recursion_limit = "256"]
|
||||
|
@ -113,8 +113,9 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
|
||||
|
||||
// Allow uses of projections that are ZSTs or from scalar fields.
|
||||
let is_consume = match context {
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy)
|
||||
| PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true,
|
||||
PlaceContext::NonMutatingUse(
|
||||
NonMutatingUseContext::Copy | NonMutatingUseContext::Move,
|
||||
) => true,
|
||||
_ => false,
|
||||
};
|
||||
if is_consume {
|
||||
@ -274,8 +275,9 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
|
||||
|
||||
PlaceContext::NonUse(_) | PlaceContext::MutatingUse(MutatingUseContext::Retag) => {}
|
||||
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy)
|
||||
| PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => {
|
||||
PlaceContext::NonMutatingUse(
|
||||
NonMutatingUseContext::Copy | NonMutatingUseContext::Move,
|
||||
) => {
|
||||
// Reads from uninitialized variables (e.g., in dead code, after
|
||||
// optimizations) require locals to be in (uninitialized) memory.
|
||||
// N.B., there can be uninitialized reads of a local visited after
|
||||
@ -291,17 +293,21 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
|
||||
}
|
||||
}
|
||||
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect)
|
||||
| PlaceContext::MutatingUse(MutatingUseContext::Store)
|
||||
| PlaceContext::MutatingUse(MutatingUseContext::AsmOutput)
|
||||
| PlaceContext::MutatingUse(MutatingUseContext::Borrow)
|
||||
| PlaceContext::MutatingUse(MutatingUseContext::AddressOf)
|
||||
| PlaceContext::MutatingUse(MutatingUseContext::Projection)
|
||||
| PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow)
|
||||
| PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow)
|
||||
| PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow)
|
||||
| PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf)
|
||||
| PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) => {
|
||||
PlaceContext::MutatingUse(
|
||||
MutatingUseContext::Store
|
||||
| MutatingUseContext::AsmOutput
|
||||
| MutatingUseContext::Borrow
|
||||
| MutatingUseContext::AddressOf
|
||||
| MutatingUseContext::Projection,
|
||||
)
|
||||
| PlaceContext::NonMutatingUse(
|
||||
NonMutatingUseContext::Inspect
|
||||
| NonMutatingUseContext::SharedBorrow
|
||||
| NonMutatingUseContext::UniqueBorrow
|
||||
| NonMutatingUseContext::ShallowBorrow
|
||||
| NonMutatingUseContext::AddressOf
|
||||
| NonMutatingUseContext::Projection,
|
||||
) => {
|
||||
self.not_ssa(local);
|
||||
}
|
||||
|
||||
|
@ -193,7 +193,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
|
||||
}
|
||||
|
||||
// Newtype of a scalar, scalar pair or vector.
|
||||
(OperandValue::Immediate(_), _) | (OperandValue::Pair(..), _)
|
||||
(OperandValue::Immediate(_) | OperandValue::Pair(..), _)
|
||||
if field.size == self.layout.size =>
|
||||
{
|
||||
assert_eq!(offset.bytes(), 0);
|
||||
|
@ -277,8 +277,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
bug!("unexpected non-pair operand");
|
||||
}
|
||||
}
|
||||
mir::CastKind::Pointer(PointerCast::MutToConstPointer)
|
||||
| mir::CastKind::Pointer(PointerCast::ArrayToPointer)
|
||||
mir::CastKind::Pointer(
|
||||
PointerCast::MutToConstPointer | PointerCast::ArrayToPointer,
|
||||
)
|
||||
| mir::CastKind::Misc => {
|
||||
assert!(bx.cx().is_backend_immediate(cast));
|
||||
let ll_t_out = bx.cx().immediate_backend_type(cast);
|
||||
@ -358,10 +359,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
bx.uitofp(llval, ll_t_out)
|
||||
}
|
||||
}
|
||||
(CastTy::Ptr(_), CastTy::Ptr(_)) | (CastTy::FnPtr, CastTy::Ptr(_)) => {
|
||||
(CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Ptr(_)) => {
|
||||
bx.pointercast(llval, ll_t_out)
|
||||
}
|
||||
(CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => {
|
||||
(CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => {
|
||||
bx.ptrtoint(llval, ll_t_out)
|
||||
}
|
||||
(CastTy::Int(_), CastTy::Ptr(_)) => {
|
||||
|
@ -2,6 +2,7 @@
|
||||
#![feature(cow_is_borrowed)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(or_patterns)]
|
||||
#![feature(proc_macro_diagnostic)]
|
||||
#![feature(proc_macro_internals)]
|
||||
#![feature(proc_macro_span)]
|
||||
|
@ -588,8 +588,10 @@ fn inner_parse_loop<'root, 'tt>(
|
||||
//
|
||||
// At the beginning of the loop, if we reach the end of the delimited submatcher,
|
||||
// we pop the stack to backtrack out of the descent.
|
||||
seq @ TokenTree::Delimited(..)
|
||||
| seq @ TokenTree::Token(Token { kind: DocComment(..), .. }) => {
|
||||
seq
|
||||
@
|
||||
(TokenTree::Delimited(..)
|
||||
| TokenTree::Token(Token { kind: DocComment(..), .. })) => {
|
||||
let lower_elts = mem::replace(&mut item.top_elts, Tt(seq));
|
||||
let idx = item.idx;
|
||||
item.stack.push(MatcherTtFrame { elts: lower_elts, idx });
|
||||
|
@ -62,8 +62,9 @@ impl hir::Pat<'_> {
|
||||
match self.kind {
|
||||
PatKind::Lit(_)
|
||||
| PatKind::Range(..)
|
||||
| PatKind::Path(hir::QPath::Resolved(Some(..), _))
|
||||
| PatKind::Path(hir::QPath::TypeRelative(..)) => true,
|
||||
| PatKind::Path(hir::QPath::Resolved(Some(..), _) | hir::QPath::TypeRelative(..)) => {
|
||||
true
|
||||
}
|
||||
|
||||
PatKind::Path(hir::QPath::Resolved(_, ref path))
|
||||
| PatKind::TupleStruct(hir::QPath::Resolved(_, ref path), ..)
|
||||
@ -141,8 +142,12 @@ impl hir::Pat<'_> {
|
||||
|
||||
pub fn simple_ident(&self) -> Option<ast::Ident> {
|
||||
match self.kind {
|
||||
PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, None)
|
||||
| PatKind::Binding(hir::BindingAnnotation::Mutable, _, ident, None) => Some(ident),
|
||||
PatKind::Binding(
|
||||
hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Mutable,
|
||||
_,
|
||||
ident,
|
||||
None,
|
||||
) => Some(ident),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -155,8 +160,8 @@ impl hir::Pat<'_> {
|
||||
PatKind::Path(hir::QPath::Resolved(_, path))
|
||||
| PatKind::TupleStruct(hir::QPath::Resolved(_, path), ..)
|
||||
| PatKind::Struct(hir::QPath::Resolved(_, path), ..) => {
|
||||
if let Res::Def(DefKind::Variant, id)
|
||||
| Res::Def(DefKind::Ctor(CtorOf::Variant, ..), id) = path.res
|
||||
if let Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..), id) =
|
||||
path.res
|
||||
{
|
||||
variants.push(id);
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
#![feature(or_patterns)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
use rustc_ast::ast;
|
||||
@ -1197,8 +1198,9 @@ impl<'a> State<'a> {
|
||||
// These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is
|
||||
// the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead
|
||||
// of `(x as i32) < ...`. We need to convince it _not_ to do that.
|
||||
(&hir::ExprKind::Cast { .. }, hir::BinOpKind::Lt)
|
||||
| (&hir::ExprKind::Cast { .. }, hir::BinOpKind::Shl) => parser::PREC_FORCE_PAREN,
|
||||
(&hir::ExprKind::Cast { .. }, hir::BinOpKind::Lt | hir::BinOpKind::Shl) => {
|
||||
parser::PREC_FORCE_PAREN
|
||||
}
|
||||
_ => left_prec,
|
||||
};
|
||||
|
||||
|
@ -375,9 +375,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||
t,
|
||||
),
|
||||
|
||||
ty::Infer(ty::FreshTy(_))
|
||||
| ty::Infer(ty::FreshIntTy(_))
|
||||
| ty::Infer(ty::FreshFloatTy(_)) => {
|
||||
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
|
||||
bug!("encountered a fresh type during canonicalization")
|
||||
}
|
||||
|
||||
|
@ -555,7 +555,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) => {
|
||||
ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => {
|
||||
// No matter what mode we are in,
|
||||
// integer/floating-point types must be equal to be
|
||||
// relatable.
|
||||
|
@ -193,7 +193,7 @@ fn msg_span_from_early_bound_and_free_regions(
|
||||
let scope = region.free_region_binding_scope(tcx);
|
||||
let node = tcx.hir().as_local_hir_id(scope).unwrap();
|
||||
let tag = match tcx.hir().find(node) {
|
||||
Some(Node::Block(_)) | Some(Node::Expr(_)) => "body",
|
||||
Some(Node::Block(_) | Node::Expr(_)) => "body",
|
||||
Some(Node::Item(it)) => item_scope_tag(&it),
|
||||
Some(Node::TraitItem(it)) => trait_item_scope_tag(&it),
|
||||
Some(Node::ImplItem(it)) => impl_item_scope_tag(&it),
|
||||
@ -1058,13 +1058,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
match (&a.kind, &b.kind) {
|
||||
(a, b) if *a == *b => true,
|
||||
(&ty::Int(_), &ty::Infer(ty::InferTy::IntVar(_)))
|
||||
| (&ty::Infer(ty::InferTy::IntVar(_)), &ty::Int(_))
|
||||
| (&ty::Infer(ty::InferTy::IntVar(_)), &ty::Infer(ty::InferTy::IntVar(_)))
|
||||
| (
|
||||
&ty::Infer(ty::InferTy::IntVar(_)),
|
||||
&ty::Int(_) | &ty::Infer(ty::InferTy::IntVar(_)),
|
||||
)
|
||||
| (&ty::Float(_), &ty::Infer(ty::InferTy::FloatVar(_)))
|
||||
| (&ty::Infer(ty::InferTy::FloatVar(_)), &ty::Float(_))
|
||||
| (&ty::Infer(ty::InferTy::FloatVar(_)), &ty::Infer(ty::InferTy::FloatVar(_))) => {
|
||||
true
|
||||
}
|
||||
| (
|
||||
&ty::Infer(ty::InferTy::FloatVar(_)),
|
||||
&ty::Float(_) | &ty::Infer(ty::InferTy::FloatVar(_)),
|
||||
) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -164,12 +164,17 @@ impl Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
(Some(rl::Region::Static), _)
|
||||
| (Some(rl::Region::Free(_, _)), _)
|
||||
| (Some(rl::Region::EarlyBound(_, _, _)), _)
|
||||
| (Some(rl::Region::LateBound(_, _, _)), _)
|
||||
| (Some(rl::Region::LateBoundAnon(_, _)), _)
|
||||
| (None, _) => {
|
||||
(
|
||||
Some(
|
||||
rl::Region::Static
|
||||
| rl::Region::Free(_, _)
|
||||
| rl::Region::EarlyBound(_, _, _)
|
||||
| rl::Region::LateBound(_, _, _)
|
||||
| rl::Region::LateBoundAnon(_, _),
|
||||
)
|
||||
| None,
|
||||
_,
|
||||
) => {
|
||||
debug!("no arg found");
|
||||
}
|
||||
}
|
||||
@ -244,12 +249,17 @@ impl Visitor<'tcx> for TyPathVisitor<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
(Some(rl::Region::Static), _)
|
||||
| (Some(rl::Region::EarlyBound(_, _, _)), _)
|
||||
| (Some(rl::Region::LateBound(_, _, _)), _)
|
||||
| (Some(rl::Region::LateBoundAnon(_, _)), _)
|
||||
| (Some(rl::Region::Free(_, _)), _)
|
||||
| (None, _) => {
|
||||
(
|
||||
Some(
|
||||
rl::Region::Static
|
||||
| rl::Region::EarlyBound(_, _, _)
|
||||
| rl::Region::LateBound(_, _, _)
|
||||
| rl::Region::LateBoundAnon(_, _)
|
||||
| rl::Region::Free(_, _),
|
||||
)
|
||||
| None,
|
||||
_,
|
||||
) => {
|
||||
debug!("no arg found");
|
||||
}
|
||||
}
|
||||
|
@ -173,9 +173,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||
ty::FreshFloatTy,
|
||||
),
|
||||
|
||||
ty::Infer(ty::FreshTy(ct))
|
||||
| ty::Infer(ty::FreshIntTy(ct))
|
||||
| ty::Infer(ty::FreshFloatTy(ct)) => {
|
||||
ty::Infer(ty::FreshTy(ct) | ty::FreshIntTy(ct) | ty::FreshFloatTy(ct)) => {
|
||||
if ct >= self.ty_freshen_count {
|
||||
bug!(
|
||||
"Encountered a freshend type with id {} \
|
||||
|
@ -512,12 +512,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||
self.tcx().lifetimes.re_static
|
||||
}
|
||||
|
||||
(&ReEmpty(_), r @ ReEarlyBound(_))
|
||||
| (r @ ReEarlyBound(_), &ReEmpty(_))
|
||||
| (&ReEmpty(_), r @ ReFree(_))
|
||||
| (r @ ReFree(_), &ReEmpty(_))
|
||||
| (&ReEmpty(_), r @ ReScope(_))
|
||||
| (r @ ReScope(_), &ReEmpty(_)) => {
|
||||
(&ReEmpty(_), r @ (ReEarlyBound(_) | ReFree(_) | ReScope(_)))
|
||||
| (r @ (ReEarlyBound(_) | ReFree(_) | ReScope(_)), &ReEmpty(_)) => {
|
||||
// All empty regions are less than early-bound, free,
|
||||
// and scope regions.
|
||||
r
|
||||
@ -542,10 +538,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
(&ReEarlyBound(_), &ReScope(s_id))
|
||||
| (&ReScope(s_id), &ReEarlyBound(_))
|
||||
| (&ReFree(_), &ReScope(s_id))
|
||||
| (&ReScope(s_id), &ReFree(_)) => {
|
||||
(&ReEarlyBound(_) | &ReFree(_), &ReScope(s_id))
|
||||
| (&ReScope(s_id), &ReEarlyBound(_) | &ReFree(_)) => {
|
||||
// A "free" region can be interpreted as "some region
|
||||
// at least as big as fr.scope". So, we can
|
||||
// reasonably compare free regions and scopes:
|
||||
@ -584,10 +578,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||
self.tcx().mk_region(ReScope(lub))
|
||||
}
|
||||
|
||||
(&ReEarlyBound(_), &ReEarlyBound(_))
|
||||
| (&ReFree(_), &ReEarlyBound(_))
|
||||
| (&ReEarlyBound(_), &ReFree(_))
|
||||
| (&ReFree(_), &ReFree(_)) => self.region_rels.lub_free_regions(a, b),
|
||||
(&ReEarlyBound(_), &ReEarlyBound(_) | &ReFree(_))
|
||||
| (&ReFree(_), &ReEarlyBound(_) | &ReFree(_)) => {
|
||||
self.region_rels.lub_free_regions(a, b)
|
||||
}
|
||||
|
||||
// For these types, we cannot define any additional
|
||||
// relationship:
|
||||
|
@ -904,7 +904,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) => {
|
||||
ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => {
|
||||
// No matter what mode we are in,
|
||||
// integer/floating-point types must be equal to be
|
||||
// relatable.
|
||||
|
@ -168,8 +168,10 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
|
||||
for outlives_bound in outlives_bounds {
|
||||
debug!("add_outlives_bounds: outlives_bound={:?}", outlives_bound);
|
||||
match outlives_bound {
|
||||
OutlivesBound::RegionSubRegion(r_a @ &ty::ReEarlyBound(_), &ty::ReVar(vid_b))
|
||||
| OutlivesBound::RegionSubRegion(r_a @ &ty::ReFree(_), &ty::ReVar(vid_b)) => {
|
||||
OutlivesBound::RegionSubRegion(
|
||||
r_a @ (&ty::ReEarlyBound(_) | &ty::ReFree(_)),
|
||||
&ty::ReVar(vid_b),
|
||||
) => {
|
||||
infcx.expect("no infcx provided but region vars found").add_given(r_a, vid_b);
|
||||
}
|
||||
OutlivesBound::RegionSubParam(r_a, param_b) => {
|
||||
|
@ -17,6 +17,7 @@
|
||||
#![feature(box_patterns)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(never_type)]
|
||||
#![feature(or_patterns)]
|
||||
#![feature(range_is_empty)]
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
|
@ -32,6 +32,7 @@
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(never_type)]
|
||||
#![feature(nll)]
|
||||
#![feature(or_patterns)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -134,7 +134,7 @@ fn get_bin_hex_repr(cx: &LateContext<'_, '_>, lit: &hir::Lit) -> Option<String>
|
||||
|
||||
if firstch == '0' {
|
||||
match src.chars().nth(1) {
|
||||
Some('x') | Some('b') => return Some(src),
|
||||
Some('x' | 'b') => return Some(src),
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
@ -356,8 +356,7 @@ fn lint_literal<'a, 'tcx>(
|
||||
match cx.tables.node_type(e.hir_id).kind {
|
||||
ty::Int(t) => {
|
||||
match lit.node {
|
||||
ast::LitKind::Int(v, ast::LitIntType::Signed(_))
|
||||
| ast::LitKind::Int(v, ast::LitIntType::Unsuffixed) => {
|
||||
ast::LitKind::Int(v, ast::LitIntType::Signed(_) | ast::LitIntType::Unsuffixed) => {
|
||||
lint_int_literal(cx, type_limits, e, lit, t, v)
|
||||
}
|
||||
_ => bug!(),
|
||||
@ -455,8 +454,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
|
||||
let (min, max) = int_ty_range(int_ty);
|
||||
let lit_val: i128 = match lit.kind {
|
||||
hir::ExprKind::Lit(ref li) => match li.node {
|
||||
ast::LitKind::Int(v, ast::LitIntType::Signed(_))
|
||||
| ast::LitKind::Int(v, ast::LitIntType::Unsuffixed) => v as i128,
|
||||
ast::LitKind::Int(
|
||||
v,
|
||||
ast::LitIntType::Signed(_) | ast::LitIntType::Unsuffixed,
|
||||
) => v as i128,
|
||||
_ => return true,
|
||||
},
|
||||
_ => bug!(),
|
||||
@ -1030,8 +1031,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
|
||||
let ty = cx.tcx.erase_regions(&t);
|
||||
let layout = match cx.layout_of(ty) {
|
||||
Ok(layout) => layout,
|
||||
Err(ty::layout::LayoutError::Unknown(_))
|
||||
| Err(ty::layout::LayoutError::SizeOverflow(_)) => return,
|
||||
Err(
|
||||
ty::layout::LayoutError::Unknown(_) | ty::layout::LayoutError::SizeOverflow(_),
|
||||
) => return,
|
||||
};
|
||||
let (variants, tag) = match layout.variants {
|
||||
Variants::Multiple {
|
||||
|
@ -56,9 +56,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
|
||||
match callee.kind {
|
||||
hir::ExprKind::Path(ref qpath) => {
|
||||
match cx.tables.qpath_res(qpath, callee.hir_id) {
|
||||
Res::Def(DefKind::Fn, def_id) | Res::Def(DefKind::AssocFn, def_id) => {
|
||||
Some(def_id)
|
||||
}
|
||||
Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) => Some(def_id),
|
||||
// `Res::Local` if it was a closure, for which we
|
||||
// do not currently support must-use linting
|
||||
_ => None,
|
||||
|
@ -5,6 +5,7 @@
|
||||
#![feature(drain_filter)]
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![feature(nll)]
|
||||
#![feature(or_patterns)]
|
||||
#![feature(proc_macro_internals)]
|
||||
#![feature(specialization)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
|
@ -1138,8 +1138,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||
fn mir_const_qualif(&self, id: DefIndex) -> mir::ConstQualifs {
|
||||
match self.kind(id) {
|
||||
EntryKind::Const(qualif, _)
|
||||
| EntryKind::AssocConst(AssocContainer::ImplDefault, qualif, _)
|
||||
| EntryKind::AssocConst(AssocContainer::ImplFinal, qualif, _) => qualif,
|
||||
| EntryKind::AssocConst(
|
||||
AssocContainer::ImplDefault | AssocContainer::ImplFinal,
|
||||
qualif,
|
||||
_,
|
||||
) => qualif,
|
||||
_ => bug!(),
|
||||
}
|
||||
}
|
||||
|
@ -250,14 +250,11 @@ pub fn provide(providers: &mut Providers<'_>) {
|
||||
// resolve! Does this work? Unsure! That's what the issue is about
|
||||
*providers = Providers {
|
||||
is_dllimport_foreign_item: |tcx, id| match tcx.native_library_kind(id) {
|
||||
Some(NativeLibraryKind::NativeUnknown) | Some(NativeLibraryKind::NativeRawDylib) => {
|
||||
true
|
||||
}
|
||||
Some(NativeLibraryKind::NativeUnknown | NativeLibraryKind::NativeRawDylib) => true,
|
||||
_ => false,
|
||||
},
|
||||
is_statically_included_foreign_item: |tcx, id| match tcx.native_library_kind(id) {
|
||||
Some(NativeLibraryKind::NativeStatic)
|
||||
| Some(NativeLibraryKind::NativeStaticNobundle) => true,
|
||||
Some(NativeLibraryKind::NativeStatic | NativeLibraryKind::NativeStaticNobundle) => true,
|
||||
_ => false,
|
||||
},
|
||||
native_library_kind: |tcx, id| {
|
||||
|
@ -420,8 +420,7 @@ impl<'hir> Map<'hir> {
|
||||
|
||||
pub fn ty_param_owner(&self, id: HirId) -> HirId {
|
||||
match self.get(id) {
|
||||
Node::Item(&Item { kind: ItemKind::Trait(..), .. })
|
||||
| Node::Item(&Item { kind: ItemKind::TraitAlias(..), .. }) => id,
|
||||
Node::Item(&Item { kind: ItemKind::Trait(..) | ItemKind::TraitAlias(..), .. }) => id,
|
||||
Node::GenericParam(_) => self.get_parent_node(id),
|
||||
_ => bug!("ty_param_owner: {} not a type parameter", self.node_to_string(id)),
|
||||
}
|
||||
@ -429,8 +428,9 @@ impl<'hir> Map<'hir> {
|
||||
|
||||
pub fn ty_param_name(&self, id: HirId) -> Name {
|
||||
match self.get(id) {
|
||||
Node::Item(&Item { kind: ItemKind::Trait(..), .. })
|
||||
| Node::Item(&Item { kind: ItemKind::TraitAlias(..), .. }) => kw::SelfUpper,
|
||||
Node::Item(&Item { kind: ItemKind::Trait(..) | ItemKind::TraitAlias(..), .. }) => {
|
||||
kw::SelfUpper
|
||||
}
|
||||
Node::GenericParam(param) => param.name.ident().name,
|
||||
_ => bug!("ty_param_name: {} not a type parameter", self.node_to_string(id)),
|
||||
}
|
||||
@ -557,11 +557,10 @@ impl<'hir> Map<'hir> {
|
||||
pub fn is_const_context(&self, hir_id: HirId) -> bool {
|
||||
let parent_id = self.get_parent_item(hir_id);
|
||||
match self.get(parent_id) {
|
||||
Node::Item(&Item { kind: ItemKind::Const(..), .. })
|
||||
Node::Item(&Item { kind: ItemKind::Const(..) | ItemKind::Static(..), .. })
|
||||
| Node::TraitItem(&TraitItem { kind: TraitItemKind::Const(..), .. })
|
||||
| Node::ImplItem(&ImplItem { kind: ImplItemKind::Const(..), .. })
|
||||
| Node::AnonConst(_)
|
||||
| Node::Item(&Item { kind: ItemKind::Static(..), .. }) => true,
|
||||
| Node::AnonConst(_) => true,
|
||||
Node::Item(&Item { kind: ItemKind::Fn(ref sig, ..), .. }) => {
|
||||
sig.header.constness == Constness::Const
|
||||
}
|
||||
@ -571,9 +570,8 @@ impl<'hir> Map<'hir> {
|
||||
|
||||
/// Whether `hir_id` corresponds to a `mod` or a crate.
|
||||
pub fn is_hir_id_module(&self, hir_id: HirId) -> bool {
|
||||
match self.get_entry(hir_id) {
|
||||
Entry { node: Node::Item(Item { kind: ItemKind::Mod(_), .. }), .. }
|
||||
| Entry { node: Node::Crate(..), .. } => true,
|
||||
match self.get_entry(hir_id).node {
|
||||
Node::Item(Item { kind: ItemKind::Mod(_), .. }) | Node::Crate(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -213,10 +213,8 @@ pub fn struct_lint_level<'s, 'd>(
|
||||
}
|
||||
(Level::Warn, Some(span)) => sess.struct_span_warn(span, ""),
|
||||
(Level::Warn, None) => sess.struct_warn(""),
|
||||
(Level::Deny, Some(span)) | (Level::Forbid, Some(span)) => {
|
||||
sess.struct_span_err(span, "")
|
||||
}
|
||||
(Level::Deny, None) | (Level::Forbid, None) => sess.struct_err(""),
|
||||
(Level::Deny | Level::Forbid, Some(span)) => sess.struct_span_err(span, ""),
|
||||
(Level::Deny | Level::Forbid, None) => sess.struct_err(""),
|
||||
};
|
||||
|
||||
// Check for future incompatibility lints and issue a stronger warning.
|
||||
|
@ -114,7 +114,7 @@ impl CodegenFnAttrs {
|
||||
|| match self.linkage {
|
||||
// These are private, so make sure we don't try to consider
|
||||
// them external.
|
||||
None | Some(Linkage::Internal) | Some(Linkage::Private) => false,
|
||||
None | Some(Linkage::Internal | Linkage::Private) => false,
|
||||
Some(_) => true,
|
||||
}
|
||||
}
|
||||
|
@ -173,9 +173,7 @@ impl<'tcx> Rvalue<'tcx> {
|
||||
let ty = op.ty(tcx, lhs_ty, rhs_ty);
|
||||
tcx.intern_tup(&[ty, tcx.types.bool])
|
||||
}
|
||||
Rvalue::UnaryOp(UnOp::Not, ref operand) | Rvalue::UnaryOp(UnOp::Neg, ref operand) => {
|
||||
operand.ty(local_decls, tcx)
|
||||
}
|
||||
Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, ref operand) => operand.ty(local_decls, tcx),
|
||||
Rvalue::Discriminant(ref place) => {
|
||||
let ty = place.ty(local_decls, tcx).ty;
|
||||
match ty.kind {
|
||||
|
@ -1115,9 +1115,11 @@ impl PlaceContext {
|
||||
/// Returns `true` if this place context represents a borrow.
|
||||
pub fn is_borrow(&self) -> bool {
|
||||
match *self {
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow)
|
||||
| PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow)
|
||||
| PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow)
|
||||
PlaceContext::NonMutatingUse(
|
||||
NonMutatingUseContext::SharedBorrow
|
||||
| NonMutatingUseContext::ShallowBorrow
|
||||
| NonMutatingUseContext::UniqueBorrow,
|
||||
)
|
||||
| PlaceContext::MutatingUse(MutatingUseContext::Borrow) => true,
|
||||
_ => false,
|
||||
}
|
||||
@ -1126,8 +1128,7 @@ impl PlaceContext {
|
||||
/// Returns `true` if this place context represents a storage live or storage dead marker.
|
||||
pub fn is_storage_marker(&self) -> bool {
|
||||
match *self {
|
||||
PlaceContext::NonUse(NonUseContext::StorageLive)
|
||||
| PlaceContext::NonUse(NonUseContext::StorageDead) => true,
|
||||
PlaceContext::NonUse(NonUseContext::StorageLive | NonUseContext::StorageDead) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -1175,9 +1176,11 @@ impl PlaceContext {
|
||||
/// Returns `true` if this place context represents an assignment statement.
|
||||
pub fn is_place_assignment(&self) -> bool {
|
||||
match *self {
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Store)
|
||||
| PlaceContext::MutatingUse(MutatingUseContext::Call)
|
||||
| PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) => true,
|
||||
PlaceContext::MutatingUse(
|
||||
MutatingUseContext::Store
|
||||
| MutatingUseContext::Call
|
||||
| MutatingUseContext::AsmOutput,
|
||||
) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -68,9 +68,12 @@ impl TypeRelation<'tcx> for Match<'tcx> {
|
||||
}
|
||||
|
||||
match (&a.kind, &b.kind) {
|
||||
(_, &ty::Infer(ty::FreshTy(_)))
|
||||
| (_, &ty::Infer(ty::FreshIntTy(_)))
|
||||
| (_, &ty::Infer(ty::FreshFloatTy(_))) => Ok(a),
|
||||
(
|
||||
_,
|
||||
&ty::Infer(ty::FreshTy(_))
|
||||
| &ty::Infer(ty::FreshIntTy(_))
|
||||
| &ty::Infer(ty::FreshFloatTy(_)),
|
||||
) => Ok(a),
|
||||
|
||||
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
|
||||
Err(TypeError::Sorts(relate::expected_found(self, &a, &b)))
|
||||
|
@ -1415,7 +1415,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
let hir_id = self.hir().as_local_hir_id(suitable_region_binding_scope).unwrap();
|
||||
let is_impl_item = match self.hir().find(hir_id) {
|
||||
Some(Node::Item(..)) | Some(Node::TraitItem(..)) => false,
|
||||
Some(Node::Item(..) | Node::TraitItem(..)) => false,
|
||||
Some(Node::ImplItem(..)) => {
|
||||
self.is_bound_region_in_impl_item(suitable_region_binding_scope)
|
||||
}
|
||||
|
@ -14,10 +14,12 @@ impl<'tcx> TyS<'tcx> {
|
||||
| Int(_)
|
||||
| Uint(_)
|
||||
| Float(_)
|
||||
| Infer(InferTy::IntVar(_))
|
||||
| Infer(InferTy::FloatVar(_))
|
||||
| Infer(InferTy::FreshIntTy(_))
|
||||
| Infer(InferTy::FreshFloatTy(_)) => true,
|
||||
| Infer(
|
||||
InferTy::IntVar(_)
|
||||
| InferTy::FloatVar(_)
|
||||
| InferTy::FreshIntTy(_)
|
||||
| InferTy::FreshFloatTy(_),
|
||||
) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -32,10 +34,12 @@ impl<'tcx> TyS<'tcx> {
|
||||
| Int(_)
|
||||
| Uint(_)
|
||||
| Float(_)
|
||||
| Infer(InferTy::IntVar(_))
|
||||
| Infer(InferTy::FloatVar(_))
|
||||
| Infer(InferTy::FreshIntTy(_))
|
||||
| Infer(InferTy::FreshFloatTy(_)) => true,
|
||||
| Infer(
|
||||
InferTy::IntVar(_)
|
||||
| InferTy::FloatVar(_)
|
||||
| InferTy::FreshIntTy(_)
|
||||
| InferTy::FreshFloatTy(_),
|
||||
) => true,
|
||||
Ref(_, x, _) | Array(x, _) | Slice(x) => x.peel_refs().is_simple_ty(),
|
||||
Tuple(tys) if tys.is_empty() => true,
|
||||
_ => false,
|
||||
|
@ -426,8 +426,7 @@ fn needs_fn_once_adapter_shim(
|
||||
// basically the same thing, so we can just return llfn.
|
||||
Ok(false)
|
||||
}
|
||||
(ty::ClosureKind::Fn, ty::ClosureKind::FnOnce)
|
||||
| (ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => {
|
||||
(ty::ClosureKind::Fn | ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => {
|
||||
// The closure fn `llfn` is a `fn(&self, ...)` or `fn(&mut
|
||||
// self, ...)`. We want a `fn(self, ...)`. We can produce
|
||||
// this by doing something like:
|
||||
@ -438,6 +437,6 @@ fn needs_fn_once_adapter_shim(
|
||||
// These are both the same at codegen time.
|
||||
Ok(true)
|
||||
}
|
||||
(ty::ClosureKind::FnMut, _) | (ty::ClosureKind::FnOnce, _) => Err(()),
|
||||
(ty::ClosureKind::FnMut | ty::ClosureKind::FnOnce, _) => Err(()),
|
||||
}
|
||||
}
|
||||
|
@ -2776,9 +2776,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
let enum_did = self.parent(did).unwrap();
|
||||
self.adt_def(enum_did).variant_with_id(did)
|
||||
}
|
||||
Res::Def(DefKind::Struct, did) | Res::Def(DefKind::Union, did) => {
|
||||
self.adt_def(did).non_enum_variant()
|
||||
}
|
||||
Res::Def(DefKind::Struct | DefKind::Union, did) => self.adt_def(did).non_enum_variant(),
|
||||
Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_did) => {
|
||||
let variant_did = self.parent(variant_ctor_did).unwrap();
|
||||
let enum_did = self.parent(variant_did).unwrap();
|
||||
|
@ -909,9 +909,9 @@ pub trait PrettyPrinter<'tcx>:
|
||||
p!(write("::{:?}", promoted));
|
||||
} else {
|
||||
match self.tcx().def_kind(did) {
|
||||
Some(DefKind::Static)
|
||||
| Some(DefKind::Const)
|
||||
| Some(DefKind::AssocConst) => p!(print_value_path(did, substs)),
|
||||
Some(DefKind::Static | DefKind::Const | DefKind::AssocConst) => {
|
||||
p!(print_value_path(did, substs))
|
||||
}
|
||||
_ => {
|
||||
if did.is_local() {
|
||||
let span = self.tcx().def_span(did);
|
||||
|
@ -1887,8 +1887,15 @@ impl<'tcx> TyS<'tcx> {
|
||||
#[inline]
|
||||
pub fn is_scalar(&self) -> bool {
|
||||
match self.kind {
|
||||
Bool | Char | Int(_) | Float(_) | Uint(_) | Infer(IntVar(_)) | Infer(FloatVar(_))
|
||||
| FnDef(..) | FnPtr(_) | RawPtr(_) => true,
|
||||
Bool
|
||||
| Char
|
||||
| Int(_)
|
||||
| Float(_)
|
||||
| Uint(_)
|
||||
| Infer(IntVar(_) | FloatVar(_))
|
||||
| FnDef(..)
|
||||
| FnPtr(_)
|
||||
| RawPtr(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -2154,8 +2161,7 @@ impl<'tcx> TyS<'tcx> {
|
||||
/// `false` means nothing -- could be sized, might not be.
|
||||
pub fn is_trivially_sized(&self, tcx: TyCtxt<'tcx>) -> bool {
|
||||
match self.kind {
|
||||
ty::Infer(ty::IntVar(_))
|
||||
| ty::Infer(ty::FloatVar(_))
|
||||
ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
|
||||
| ty::Uint(_)
|
||||
| ty::Int(_)
|
||||
| ty::Bool
|
||||
@ -2186,9 +2192,7 @@ impl<'tcx> TyS<'tcx> {
|
||||
|
||||
ty::Bound(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Infer(ty::FreshTy(_))
|
||||
| ty::Infer(ty::FreshIntTy(_))
|
||||
| ty::Infer(ty::FreshFloatTy(_)) => {
|
||||
| ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
|
||||
bug!("`is_trivially_sized` applied to unexpected type: {:?}", self)
|
||||
}
|
||||
}
|
||||
|
@ -316,10 +316,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
break;
|
||||
}
|
||||
}
|
||||
(ty::Projection(_), _)
|
||||
| (ty::Opaque(..), _)
|
||||
| (_, ty::Projection(_))
|
||||
| (_, ty::Opaque(..)) => {
|
||||
(ty::Projection(_) | ty::Opaque(..), _)
|
||||
| (_, ty::Projection(_) | ty::Opaque(..)) => {
|
||||
// If either side is a projection, attempt to
|
||||
// progress via normalization. (Should be safe to
|
||||
// apply to both sides as normalization is
|
||||
|
@ -407,8 +407,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
self.cannot_uniquely_borrow_by_two_closures(span, &desc_place, issued_span, None)
|
||||
}
|
||||
|
||||
(BorrowKind::Mut { .. }, BorrowKind::Shallow)
|
||||
| (BorrowKind::Unique, BorrowKind::Shallow) => {
|
||||
(BorrowKind::Mut { .. } | BorrowKind::Unique, BorrowKind::Shallow) => {
|
||||
if let Some(immutable_section_description) =
|
||||
self.classify_immutable_section(issued_borrow.assigned_place)
|
||||
{
|
||||
@ -489,12 +488,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
)
|
||||
}
|
||||
|
||||
(BorrowKind::Shared, BorrowKind::Shared)
|
||||
| (BorrowKind::Shared, BorrowKind::Shallow)
|
||||
| (BorrowKind::Shallow, BorrowKind::Mut { .. })
|
||||
| (BorrowKind::Shallow, BorrowKind::Unique)
|
||||
| (BorrowKind::Shallow, BorrowKind::Shared)
|
||||
| (BorrowKind::Shallow, BorrowKind::Shallow) => unreachable!(),
|
||||
(BorrowKind::Shared, BorrowKind::Shared | BorrowKind::Shallow)
|
||||
| (
|
||||
BorrowKind::Shallow,
|
||||
BorrowKind::Mut { .. }
|
||||
| BorrowKind::Unique
|
||||
| BorrowKind::Shared
|
||||
| BorrowKind::Shallow,
|
||||
) => unreachable!(),
|
||||
};
|
||||
|
||||
if issued_spans == borrow_spans {
|
||||
@ -1426,17 +1427,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// PATTERN;) then make the error refer to that local, rather than the
|
||||
// place being assigned later.
|
||||
let (place_description, assigned_span) = match local_decl {
|
||||
Some(LocalDecl { local_info: LocalInfo::User(ClearCrossCrate::Clear), .. })
|
||||
| Some(LocalDecl {
|
||||
Some(LocalDecl {
|
||||
local_info:
|
||||
LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
|
||||
opt_match_place: None,
|
||||
..
|
||||
}))),
|
||||
LocalInfo::User(
|
||||
ClearCrossCrate::Clear
|
||||
| ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
|
||||
opt_match_place: None,
|
||||
..
|
||||
})),
|
||||
)
|
||||
| LocalInfo::StaticRef { .. }
|
||||
| LocalInfo::Other,
|
||||
..
|
||||
})
|
||||
| Some(LocalDecl { local_info: LocalInfo::StaticRef { .. }, .. })
|
||||
| Some(LocalDecl { local_info: LocalInfo::Other, .. })
|
||||
| None => (self.describe_any_place(place.as_ref()), assigned_span),
|
||||
Some(decl) => (self.describe_any_place(err_place.as_ref()), decl.source_info.span),
|
||||
};
|
||||
|
@ -484,9 +484,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// this by hooking into the pretty printer and telling it to label the
|
||||
// lifetimes without names with the value `'0`.
|
||||
match ty.kind {
|
||||
ty::Ref(ty::RegionKind::ReLateBound(_, br), _, _)
|
||||
| ty::Ref(
|
||||
ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }),
|
||||
ty::Ref(
|
||||
ty::RegionKind::ReLateBound(_, br)
|
||||
| ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }),
|
||||
_,
|
||||
_,
|
||||
) => printer.region_highlight_mode.highlighting_bound_region(*br, counter),
|
||||
|
@ -137,12 +137,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
PlaceRef { local: _, projection: [.., ProjectionElem::Index(_)] }
|
||||
| PlaceRef { local: _, projection: [.., ProjectionElem::ConstantIndex { .. }] }
|
||||
| PlaceRef { local: _, projection: [.., ProjectionElem::Subslice { .. }] }
|
||||
| PlaceRef { local: _, projection: [.., ProjectionElem::Downcast(..)] } => {
|
||||
bug!("Unexpected immutable place.")
|
||||
}
|
||||
PlaceRef {
|
||||
local: _,
|
||||
projection:
|
||||
[.., ProjectionElem::Index(_)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::Downcast(..)],
|
||||
} => bug!("Unexpected immutable place."),
|
||||
}
|
||||
|
||||
debug!("report_mutability_error: item_msg={:?}, reason={:?}", item_msg, reason);
|
||||
@ -510,21 +512,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
tables.node_type_opt(func.hir_id).as_ref().map(|ty| &ty.kind)
|
||||
{
|
||||
let arg = match hir.get_if_local(*def_id) {
|
||||
Some(hir::Node::Item(hir::Item {
|
||||
ident,
|
||||
kind: hir::ItemKind::Fn(sig, ..),
|
||||
..
|
||||
}))
|
||||
| Some(hir::Node::TraitItem(hir::TraitItem {
|
||||
ident,
|
||||
kind: hir::TraitItemKind::Fn(sig, _),
|
||||
..
|
||||
}))
|
||||
| Some(hir::Node::ImplItem(hir::ImplItem {
|
||||
ident,
|
||||
kind: hir::ImplItemKind::Fn(sig, _),
|
||||
..
|
||||
})) => Some(
|
||||
Some(
|
||||
hir::Node::Item(hir::Item {
|
||||
ident, kind: hir::ItemKind::Fn(sig, ..), ..
|
||||
})
|
||||
| hir::Node::TraitItem(hir::TraitItem {
|
||||
ident,
|
||||
kind: hir::TraitItemKind::Fn(sig, _),
|
||||
..
|
||||
})
|
||||
| hir::Node::ImplItem(hir::ImplItem {
|
||||
ident,
|
||||
kind: hir::ImplItemKind::Fn(sig, _),
|
||||
..
|
||||
}),
|
||||
) => Some(
|
||||
arg_pos
|
||||
.and_then(|pos| {
|
||||
sig.decl.inputs.get(
|
||||
|
@ -577,9 +577,12 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
// to search anything here.
|
||||
}
|
||||
|
||||
(GenericArgKind::Lifetime(_), _)
|
||||
| (GenericArgKind::Type(_), _)
|
||||
| (GenericArgKind::Const(_), _) => {
|
||||
(
|
||||
GenericArgKind::Lifetime(_)
|
||||
| GenericArgKind::Type(_)
|
||||
| GenericArgKind::Const(_),
|
||||
_,
|
||||
) => {
|
||||
// I *think* that HIR lowering should ensure this
|
||||
// doesn't happen, even in erroneous
|
||||
// programs. Else we should use delay-span-bug.
|
||||
|
@ -359,14 +359,15 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
|
||||
// have already taken the reservation
|
||||
}
|
||||
|
||||
(Read(_), BorrowKind::Shallow)
|
||||
| (Read(_), BorrowKind::Shared)
|
||||
| (Read(ReadKind::Borrow(BorrowKind::Shallow)), BorrowKind::Unique)
|
||||
| (Read(ReadKind::Borrow(BorrowKind::Shallow)), BorrowKind::Mut { .. }) => {
|
||||
(Read(_), BorrowKind::Shallow | BorrowKind::Shared)
|
||||
| (
|
||||
Read(ReadKind::Borrow(BorrowKind::Shallow)),
|
||||
BorrowKind::Unique | BorrowKind::Mut { .. },
|
||||
) => {
|
||||
// Reads don't invalidate shared or shallow borrows
|
||||
}
|
||||
|
||||
(Read(_), BorrowKind::Unique) | (Read(_), BorrowKind::Mut { .. }) => {
|
||||
(Read(_), BorrowKind::Unique | BorrowKind::Mut { .. }) => {
|
||||
// Reading from mere reservations of mutable-borrows is OK.
|
||||
if !is_active(&this.dominators, borrow, location) {
|
||||
// If the borrow isn't active yet, reads don't invalidate it
|
||||
@ -379,7 +380,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
|
||||
this.generate_invalidates(borrow_index, location);
|
||||
}
|
||||
|
||||
(Reservation(_), _) | (Activation(_, _), _) | (Write(_), _) => {
|
||||
(Reservation(_) | Activation(_, _) | Write(_), _) => {
|
||||
// unique or mutable borrows are invalidated by writes.
|
||||
// Reservations count as writes since we need to check
|
||||
// that activating the borrow will be OK
|
||||
|
@ -991,19 +991,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
Control::Continue
|
||||
}
|
||||
|
||||
(Read(_), BorrowKind::Shared)
|
||||
| (Read(_), BorrowKind::Shallow)
|
||||
| (Read(ReadKind::Borrow(BorrowKind::Shallow)), BorrowKind::Unique)
|
||||
| (Read(ReadKind::Borrow(BorrowKind::Shallow)), BorrowKind::Mut { .. }) => {
|
||||
Control::Continue
|
||||
}
|
||||
(Read(_), BorrowKind::Shared | BorrowKind::Shallow)
|
||||
| (
|
||||
Read(ReadKind::Borrow(BorrowKind::Shallow)),
|
||||
BorrowKind::Unique | BorrowKind::Mut { .. },
|
||||
) => Control::Continue,
|
||||
|
||||
(Write(WriteKind::Move), BorrowKind::Shallow) => {
|
||||
// Handled by initialization checks.
|
||||
Control::Continue
|
||||
}
|
||||
|
||||
(Read(kind), BorrowKind::Unique) | (Read(kind), BorrowKind::Mut { .. }) => {
|
||||
(Read(kind), BorrowKind::Unique | BorrowKind::Mut { .. }) => {
|
||||
// Reading from mere reservations of mutable-borrows is OK.
|
||||
if !is_active(&this.dominators, borrow, location) {
|
||||
assert!(allow_two_phase_borrow(borrow.kind));
|
||||
@ -1024,12 +1023,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
Control::Break
|
||||
}
|
||||
|
||||
(Reservation(WriteKind::MutableBorrow(bk)), BorrowKind::Shallow)
|
||||
| (Reservation(WriteKind::MutableBorrow(bk)), BorrowKind::Shared)
|
||||
if {
|
||||
tcx.migrate_borrowck()
|
||||
&& this.borrow_set.location_map.contains_key(&location)
|
||||
} =>
|
||||
(
|
||||
Reservation(WriteKind::MutableBorrow(bk)),
|
||||
BorrowKind::Shallow | BorrowKind::Shared,
|
||||
) if {
|
||||
tcx.migrate_borrowck() && this.borrow_set.location_map.contains_key(&location)
|
||||
} =>
|
||||
{
|
||||
let bi = this.borrow_set.location_map[&location];
|
||||
debug!(
|
||||
@ -1048,7 +1047,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
Control::Continue
|
||||
}
|
||||
|
||||
(Reservation(kind), _) | (Activation(kind, _), _) | (Write(kind), _) => {
|
||||
(Reservation(kind) | Activation(kind, _) | Write(kind), _) => {
|
||||
match rw {
|
||||
Reservation(..) => {
|
||||
debug!(
|
||||
@ -1916,10 +1915,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
let the_place_err;
|
||||
|
||||
match kind {
|
||||
Reservation(WriteKind::MutableBorrow(borrow_kind @ BorrowKind::Unique))
|
||||
| Reservation(WriteKind::MutableBorrow(borrow_kind @ BorrowKind::Mut { .. }))
|
||||
| Write(WriteKind::MutableBorrow(borrow_kind @ BorrowKind::Unique))
|
||||
| Write(WriteKind::MutableBorrow(borrow_kind @ BorrowKind::Mut { .. })) => {
|
||||
Reservation(WriteKind::MutableBorrow(
|
||||
borrow_kind @ (BorrowKind::Unique | BorrowKind::Mut { .. }),
|
||||
))
|
||||
| Write(WriteKind::MutableBorrow(
|
||||
borrow_kind @ (BorrowKind::Unique | BorrowKind::Mut { .. }),
|
||||
)) => {
|
||||
let is_local_mutation_allowed = match borrow_kind {
|
||||
BorrowKind::Unique => LocalMutationIsAllowed::Yes,
|
||||
BorrowKind::Mut { .. } => is_local_mutation_allowed,
|
||||
@ -1949,14 +1950,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
Reservation(WriteKind::Move)
|
||||
| Write(WriteKind::Move)
|
||||
| Reservation(WriteKind::StorageDeadOrDrop)
|
||||
| Reservation(WriteKind::MutableBorrow(BorrowKind::Shared))
|
||||
| Reservation(WriteKind::MutableBorrow(BorrowKind::Shallow))
|
||||
| Write(WriteKind::StorageDeadOrDrop)
|
||||
| Write(WriteKind::MutableBorrow(BorrowKind::Shared))
|
||||
| Write(WriteKind::MutableBorrow(BorrowKind::Shallow)) => {
|
||||
Reservation(
|
||||
WriteKind::Move
|
||||
| WriteKind::StorageDeadOrDrop
|
||||
| WriteKind::MutableBorrow(BorrowKind::Shared)
|
||||
| WriteKind::MutableBorrow(BorrowKind::Shallow),
|
||||
)
|
||||
| Write(
|
||||
WriteKind::Move
|
||||
| WriteKind::StorageDeadOrDrop
|
||||
| WriteKind::MutableBorrow(BorrowKind::Shared)
|
||||
| WriteKind::MutableBorrow(BorrowKind::Shallow),
|
||||
) => {
|
||||
if let (Err(_), true) = (
|
||||
self.is_mutable(place.as_ref(), is_local_mutation_allowed),
|
||||
self.errors_buffer.is_empty(),
|
||||
@ -1980,11 +1985,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// permission checks are done at Reservation point.
|
||||
return false;
|
||||
}
|
||||
Read(ReadKind::Borrow(BorrowKind::Unique))
|
||||
| Read(ReadKind::Borrow(BorrowKind::Mut { .. }))
|
||||
| Read(ReadKind::Borrow(BorrowKind::Shared))
|
||||
| Read(ReadKind::Borrow(BorrowKind::Shallow))
|
||||
| Read(ReadKind::Copy) => {
|
||||
Read(
|
||||
ReadKind::Borrow(
|
||||
BorrowKind::Unique
|
||||
| BorrowKind::Mut { .. }
|
||||
| BorrowKind::Shared
|
||||
| BorrowKind::Shallow,
|
||||
)
|
||||
| ReadKind::Copy,
|
||||
) => {
|
||||
// Access authorized
|
||||
return false;
|
||||
}
|
||||
@ -2152,10 +2161,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
upvar, is_local_mutation_allowed, place
|
||||
);
|
||||
match (upvar.mutability, is_local_mutation_allowed) {
|
||||
(Mutability::Not, LocalMutationIsAllowed::No)
|
||||
| (Mutability::Not, LocalMutationIsAllowed::ExceptUpvars) => {
|
||||
Err(place)
|
||||
}
|
||||
(
|
||||
Mutability::Not,
|
||||
LocalMutationIsAllowed::No
|
||||
| LocalMutationIsAllowed::ExceptUpvars,
|
||||
) => Err(place),
|
||||
(Mutability::Not, LocalMutationIsAllowed::Yes)
|
||||
| (Mutability::Mut, _) => {
|
||||
// Subtle: this is an upvar
|
||||
|
@ -377,11 +377,16 @@ fn place_projection_conflict<'tcx>(
|
||||
Overlap::Disjoint
|
||||
}
|
||||
}
|
||||
(ProjectionElem::Index(..), ProjectionElem::Index(..))
|
||||
| (ProjectionElem::Index(..), ProjectionElem::ConstantIndex { .. })
|
||||
| (ProjectionElem::Index(..), ProjectionElem::Subslice { .. })
|
||||
| (ProjectionElem::ConstantIndex { .. }, ProjectionElem::Index(..))
|
||||
| (ProjectionElem::Subslice { .. }, ProjectionElem::Index(..)) => {
|
||||
(
|
||||
ProjectionElem::Index(..),
|
||||
ProjectionElem::Index(..)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subslice { .. },
|
||||
)
|
||||
| (
|
||||
ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. },
|
||||
ProjectionElem::Index(..),
|
||||
) => {
|
||||
// Array indexes (`a[0]` vs. `a[i]`). These can either be disjoint
|
||||
// (if the indexes differ) or equal (if they are the same).
|
||||
match bias {
|
||||
@ -519,12 +524,15 @@ fn place_projection_conflict<'tcx>(
|
||||
debug!("place_element_conflict: DISJOINT-OR-EQ-SLICE-SUBSLICES");
|
||||
Overlap::EqualOrDisjoint
|
||||
}
|
||||
(ProjectionElem::Deref, _)
|
||||
| (ProjectionElem::Field(..), _)
|
||||
| (ProjectionElem::Index(..), _)
|
||||
| (ProjectionElem::ConstantIndex { .. }, _)
|
||||
| (ProjectionElem::Subslice { .. }, _)
|
||||
| (ProjectionElem::Downcast(..), _) => bug!(
|
||||
(
|
||||
ProjectionElem::Deref
|
||||
| ProjectionElem::Field(..)
|
||||
| ProjectionElem::Index(..)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::Downcast(..),
|
||||
_,
|
||||
) => bug!(
|
||||
"mismatched projections in place_element_conflict: {:?} and {:?}",
|
||||
pi1_elem,
|
||||
pi2_elem
|
||||
|
@ -2269,22 +2269,18 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
let cast_ty_to = CastTy::from_ty(ty);
|
||||
match (cast_ty_from, cast_ty_to) {
|
||||
(None, _)
|
||||
| (_, None)
|
||||
| (_, Some(CastTy::FnPtr))
|
||||
| (_, None | Some(CastTy::FnPtr))
|
||||
| (Some(CastTy::Float), Some(CastTy::Ptr(_)))
|
||||
| (Some(CastTy::Ptr(_)), Some(CastTy::Float))
|
||||
| (Some(CastTy::FnPtr), Some(CastTy::Float)) => {
|
||||
| (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Float)) => {
|
||||
span_mirbug!(self, rvalue, "Invalid cast {:?} -> {:?}", ty_from, ty,)
|
||||
}
|
||||
(Some(CastTy::Int(_)), Some(CastTy::Int(_)))
|
||||
| (Some(CastTy::Float), Some(CastTy::Int(_)))
|
||||
| (Some(CastTy::Int(_)), Some(CastTy::Float))
|
||||
| (Some(CastTy::Float), Some(CastTy::Float))
|
||||
| (Some(CastTy::Ptr(_)), Some(CastTy::Int(_)))
|
||||
| (Some(CastTy::FnPtr), Some(CastTy::Int(_)))
|
||||
| (Some(CastTy::Int(_)), Some(CastTy::Ptr(_)))
|
||||
| (Some(CastTy::Ptr(_)), Some(CastTy::Ptr(_)))
|
||||
| (Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => (),
|
||||
(
|
||||
Some(CastTy::Int(_)),
|
||||
Some(CastTy::Int(_) | CastTy::Float | CastTy::Ptr(_)),
|
||||
)
|
||||
| (Some(CastTy::Float), Some(CastTy::Int(_) | CastTy::Float))
|
||||
| (Some(CastTy::Ptr(_)), Some(CastTy::Int(_) | CastTy::Ptr(_)))
|
||||
| (Some(CastTy::FnPtr), Some(CastTy::Int(_) | CastTy::Ptr(_))) => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2294,12 +2290,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
self.add_reborrow_constraint(&body, location, region, borrowed_place);
|
||||
}
|
||||
|
||||
Rvalue::BinaryOp(BinOp::Eq, left, right)
|
||||
| Rvalue::BinaryOp(BinOp::Ne, left, right)
|
||||
| Rvalue::BinaryOp(BinOp::Lt, left, right)
|
||||
| Rvalue::BinaryOp(BinOp::Le, left, right)
|
||||
| Rvalue::BinaryOp(BinOp::Gt, left, right)
|
||||
| Rvalue::BinaryOp(BinOp::Ge, left, right) => {
|
||||
Rvalue::BinaryOp(
|
||||
BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge,
|
||||
left,
|
||||
right,
|
||||
) => {
|
||||
let ty_left = left.ty(*body, tcx);
|
||||
if let ty::RawPtr(_) | ty::FnPtr(_) = ty_left.kind {
|
||||
let ty_right = right.ty(*body, tcx);
|
||||
|
@ -341,7 +341,7 @@ pub fn const_eval_raw_provider<'tcx>(
|
||||
// because any code that existed before validation could not have failed
|
||||
// validation thus preventing such a hard error from being a backwards
|
||||
// compatibility hazard
|
||||
Some(DefKind::Const) | Some(DefKind::AssocConst) => {
|
||||
Some(DefKind::Const | DefKind::AssocConst) => {
|
||||
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
|
||||
err.report_as_lint(
|
||||
tcx.at(tcx.def_span(def_id)),
|
||||
|
@ -25,9 +25,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
self.unsize_into(src, dest)?;
|
||||
}
|
||||
|
||||
Misc
|
||||
| Pointer(PointerCast::MutToConstPointer)
|
||||
| Pointer(PointerCast::ArrayToPointer) => {
|
||||
Misc | Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer) => {
|
||||
let src = self.read_immediate(src)?;
|
||||
let res = self.cast_immediate(src, dest.layout)?;
|
||||
self.write_immediate(res, dest)?;
|
||||
@ -299,8 +297,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
) -> InterpResult<'tcx> {
|
||||
trace!("Unsizing {:?} into {:?}", src, dest);
|
||||
match (&src.layout.ty.kind, &dest.layout.ty.kind) {
|
||||
(&ty::Ref(_, s, _), &ty::Ref(_, d, _))
|
||||
| (&ty::Ref(_, s, _), &ty::RawPtr(TypeAndMut { ty: d, .. }))
|
||||
(&ty::Ref(_, s, _), &ty::Ref(_, d, _) | &ty::RawPtr(TypeAndMut { ty: d, .. }))
|
||||
| (&ty::RawPtr(TypeAndMut { ty: s, .. }), &ty::RawPtr(TypeAndMut { ty: d, .. })) => {
|
||||
self.unsize_into_ptr(src, dest, s, d)
|
||||
}
|
||||
|
@ -153,8 +153,10 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> {
|
||||
match self.value {
|
||||
LocalValue::Dead => throw_ub!(DeadLocal),
|
||||
LocalValue::Live(Operand::Indirect(mplace)) => Ok(Err(mplace)),
|
||||
ref mut local @ LocalValue::Live(Operand::Immediate(_))
|
||||
| ref mut local @ LocalValue::Uninitialized => Ok(Ok(local)),
|
||||
ref mut
|
||||
local @ (LocalValue::Live(Operand::Immediate(_)) | LocalValue::Uninitialized) => {
|
||||
Ok(Ok(local))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -630,7 +632,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
// FIXME: The above is likely untrue. See
|
||||
// <https://github.com/rust-lang/rust/pull/70004#issuecomment-602022110>. Is it
|
||||
// okay to ignore `StorageDead`/`StorageLive` annotations during CTFE?
|
||||
Some(DefKind::Static) | Some(DefKind::Const) | Some(DefKind::AssocConst) => {}
|
||||
Some(DefKind::Static | DefKind::Const | DefKind::AssocConst) => {}
|
||||
_ => {
|
||||
// Mark locals that use `Storage*` annotations as dead on function entry.
|
||||
let always_live = AlwaysLiveLocals::new(self.body());
|
||||
|
@ -230,14 +230,15 @@ impl<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx
|
||||
// and thus ok.
|
||||
(InternMode::Static, hir::Mutability::Mut) => {}
|
||||
// we statically prevent `&mut T` via `const_qualif` and double check this here
|
||||
(InternMode::ConstBase, hir::Mutability::Mut)
|
||||
| (InternMode::Const, hir::Mutability::Mut) => match referenced_ty.kind {
|
||||
ty::Array(_, n)
|
||||
if n.eval_usize(self.ecx.tcx.tcx, self.ecx.param_env) == 0 => {}
|
||||
ty::Slice(_)
|
||||
if mplace.meta.unwrap_meta().to_machine_usize(self.ecx)? == 0 => {}
|
||||
_ => bug!("const qualif failed to prevent mutable references"),
|
||||
},
|
||||
(InternMode::ConstBase | InternMode::Const, hir::Mutability::Mut) => {
|
||||
match referenced_ty.kind {
|
||||
ty::Array(_, n)
|
||||
if n.eval_usize(self.ecx.tcx.tcx, self.ecx.param_env) == 0 => {}
|
||||
ty::Slice(_)
|
||||
if mplace.meta.unwrap_meta().to_machine_usize(self.ecx)? == 0 => {}
|
||||
_ => bug!("const qualif failed to prevent mutable references"),
|
||||
}
|
||||
}
|
||||
}
|
||||
// Compute the mutability with which we'll start visiting the allocation. This is
|
||||
// what gets changed when we encounter an `UnsafeCell`.
|
||||
|
@ -262,7 +262,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
||||
// Deallocating global memory -- always an error
|
||||
return Err(match self.tcx.alloc_map.lock().get(ptr.alloc_id) {
|
||||
Some(GlobalAlloc::Function(..)) => err_ub_format!("deallocating a function"),
|
||||
Some(GlobalAlloc::Static(..)) | Some(GlobalAlloc::Memory(..)) => {
|
||||
Some(GlobalAlloc::Static(..) | GlobalAlloc::Memory(..)) => {
|
||||
err_ub_format!("deallocating static memory")
|
||||
}
|
||||
None => err_ub!(PointerUseAfterFree(ptr.alloc_id)),
|
||||
|
@ -822,8 +822,7 @@ fn find_vtable_types_for_unsizing<'tcx>(
|
||||
};
|
||||
|
||||
match (&source_ty.kind, &target_ty.kind) {
|
||||
(&ty::Ref(_, a, _), &ty::Ref(_, b, _))
|
||||
| (&ty::Ref(_, a, _), &ty::RawPtr(ty::TypeAndMut { ty: b, .. }))
|
||||
(&ty::Ref(_, a, _), &ty::Ref(_, b, _) | &ty::RawPtr(ty::TypeAndMut { ty: b, .. }))
|
||||
| (&ty::RawPtr(ty::TypeAndMut { ty: a, .. }), &ty::RawPtr(ty::TypeAndMut { ty: b, .. })) => {
|
||||
ptr_vtable(a, b)
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
|
||||
let trait_ = tcx.trait_of_item(def_id).unwrap();
|
||||
let adjustment = match tcx.fn_trait_kind_from_lang_item(trait_) {
|
||||
Some(ty::ClosureKind::FnOnce) => Adjustment::Identity,
|
||||
Some(ty::ClosureKind::FnMut) | Some(ty::ClosureKind::Fn) => Adjustment::Deref,
|
||||
Some(ty::ClosureKind::FnMut | ty::ClosureKind::Fn) => Adjustment::Deref,
|
||||
None => bug!("fn pointer {:?} is not an fn", ty),
|
||||
};
|
||||
// HACK: we need the "real" argument types for the MIR,
|
||||
|
@ -341,8 +341,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
|
||||
|
||||
Rvalue::AddressOf(Mutability::Mut, _) => self.check_op(ops::MutAddressOf),
|
||||
|
||||
Rvalue::Ref(_, BorrowKind::Shared, ref place)
|
||||
| Rvalue::Ref(_, BorrowKind::Shallow, ref place)
|
||||
Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Shallow, ref place)
|
||||
| Rvalue::AddressOf(Mutability::Not, ref place) => {
|
||||
let borrowed_place_has_mut_interior = qualifs::in_place::<HasMutInterior, _>(
|
||||
&self.item,
|
||||
@ -360,9 +359,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
|
||||
let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
|
||||
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
|
||||
|
||||
if let (CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) =
|
||||
(cast_in, cast_out)
|
||||
{
|
||||
if let (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) = (cast_in, cast_out) {
|
||||
self.check_op(ops::RawPtrToIntCast);
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||
let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
|
||||
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
|
||||
match (cast_in, cast_out) {
|
||||
(CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => {
|
||||
(CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => {
|
||||
self.require_unsafe(
|
||||
"cast of pointer to int",
|
||||
"casting pointers to integers in constants",
|
||||
|
@ -156,8 +156,10 @@ fn eliminate_self_assignments(body: &mut Body<'_>, def_use_analysis: &DefUseAnal
|
||||
let location = def.location;
|
||||
if let Some(stmt) = body[location.block].statements.get(location.statement_index) {
|
||||
match &stmt.kind {
|
||||
StatementKind::Assign(box (place, Rvalue::Use(Operand::Copy(src_place))))
|
||||
| StatementKind::Assign(box (place, Rvalue::Use(Operand::Move(src_place)))) => {
|
||||
StatementKind::Assign(box (
|
||||
place,
|
||||
Rvalue::Use(Operand::Copy(src_place) | Operand::Move(src_place)),
|
||||
)) => {
|
||||
if let (Some(local), Some(src_local)) =
|
||||
(place.as_local(), src_place.as_local())
|
||||
{
|
||||
|
@ -543,7 +543,7 @@ impl<'tcx> Validator<'_, 'tcx> {
|
||||
let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
|
||||
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
|
||||
match (cast_in, cast_out) {
|
||||
(CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => {
|
||||
(CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => {
|
||||
// in normal functions, mark such casts as not promotable
|
||||
return Err(Unpromotable);
|
||||
}
|
||||
|
@ -165,21 +165,26 @@ fn check_rvalue(
|
||||
let cast_in = CastTy::from_ty(operand.ty(body, tcx)).expect("bad input type for cast");
|
||||
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
|
||||
match (cast_in, cast_out) {
|
||||
(CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => {
|
||||
(CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => {
|
||||
Err((span, "casting pointers to ints is unstable in const fn".into()))
|
||||
}
|
||||
_ => check_operand(tcx, operand, span, def_id, body),
|
||||
}
|
||||
}
|
||||
Rvalue::Cast(CastKind::Pointer(PointerCast::MutToConstPointer), operand, _)
|
||||
| Rvalue::Cast(CastKind::Pointer(PointerCast::ArrayToPointer), operand, _) => {
|
||||
check_operand(tcx, operand, span, def_id, body)
|
||||
}
|
||||
Rvalue::Cast(CastKind::Pointer(PointerCast::UnsafeFnPointer), _, _)
|
||||
| Rvalue::Cast(CastKind::Pointer(PointerCast::ClosureFnPointer(_)), _, _)
|
||||
| Rvalue::Cast(CastKind::Pointer(PointerCast::ReifyFnPointer), _, _) => {
|
||||
Err((span, "function pointer casts are not allowed in const fn".into()))
|
||||
}
|
||||
Rvalue::Cast(
|
||||
CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer),
|
||||
operand,
|
||||
_,
|
||||
) => check_operand(tcx, operand, span, def_id, body),
|
||||
Rvalue::Cast(
|
||||
CastKind::Pointer(
|
||||
PointerCast::UnsafeFnPointer
|
||||
| PointerCast::ClosureFnPointer(_)
|
||||
| PointerCast::ReifyFnPointer,
|
||||
),
|
||||
_,
|
||||
_,
|
||||
) => Err((span, "function pointer casts are not allowed in const fn".into())),
|
||||
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, _) => {
|
||||
Err((span, "unsizing casts are not allowed in const fn".into()))
|
||||
}
|
||||
|
@ -122,8 +122,10 @@ pub fn sanity_check_via_rustc_peek<'tcx, A>(
|
||||
|
||||
match (call.kind, peek_rval) {
|
||||
(PeekCallKind::ByRef, mir::Rvalue::Ref(_, _, place))
|
||||
| (PeekCallKind::ByVal, mir::Rvalue::Use(mir::Operand::Move(place)))
|
||||
| (PeekCallKind::ByVal, mir::Rvalue::Use(mir::Operand::Copy(place))) => {
|
||||
| (
|
||||
PeekCallKind::ByVal,
|
||||
mir::Rvalue::Use(mir::Operand::Move(place) | mir::Operand::Copy(place)),
|
||||
) => {
|
||||
let loc = Location { block: bb, statement_index };
|
||||
cursor.seek_before(loc);
|
||||
let state = cursor.get();
|
||||
|
@ -87,7 +87,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyArmIdentity {
|
||||
fn match_get_variant_field<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, Local, VarField<'tcx>)> {
|
||||
match &stmt.kind {
|
||||
StatementKind::Assign(box (place_into, rvalue_from)) => match rvalue_from {
|
||||
Rvalue::Use(Operand::Copy(pf)) | Rvalue::Use(Operand::Move(pf)) => {
|
||||
Rvalue::Use(Operand::Copy(pf) | Operand::Move(pf)) => {
|
||||
let local_into = place_into.as_local()?;
|
||||
let (local_from, vf) = match_variant_field_place(*pf)?;
|
||||
Some((local_into, local_from, vf))
|
||||
|
@ -232,7 +232,7 @@ impl<'tcx> Visitor<'tcx> for DefsUsesVisitor {
|
||||
fn visit_local(&mut self, &local: &Local, context: PlaceContext, _: Location) {
|
||||
match categorize(context) {
|
||||
Some(DefUse::Def) => self.defs_uses.add_def(local),
|
||||
Some(DefUse::Use) | Some(DefUse::Drop) => self.defs_uses.add_use(local),
|
||||
Some(DefUse::Use | DefUse::Drop) => self.defs_uses.add_use(local),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
@ -807,12 +807,12 @@ fn write_mir_sig(
|
||||
trace!("write_mir_sig: {:?}", src.instance);
|
||||
let kind = tcx.def_kind(src.def_id());
|
||||
let is_function = match kind {
|
||||
Some(DefKind::Fn) | Some(DefKind::AssocFn) | Some(DefKind::Ctor(..)) => true,
|
||||
Some(DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..)) => true,
|
||||
_ => tcx.is_closure(src.def_id()),
|
||||
};
|
||||
match (kind, src.promoted) {
|
||||
(_, Some(i)) => write!(w, "{:?} in ", i)?,
|
||||
(Some(DefKind::Const), _) | (Some(DefKind::AssocConst), _) => write!(w, "const ")?,
|
||||
(Some(DefKind::Const | DefKind::AssocConst), _) => write!(w, "const ")?,
|
||||
(Some(DefKind::Static), _) => {
|
||||
write!(w, "static {}", if tcx.is_mutable_static(src.def_id()) { "mut " } else { "" })?
|
||||
}
|
||||
|
@ -582,7 +582,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// enough elements.
|
||||
Some(1)
|
||||
}
|
||||
(Ordering::Equal, &Some(_)) | (Ordering::Greater, &Some(_)) => {
|
||||
(Ordering::Equal | Ordering::Greater, &Some(_)) => {
|
||||
// This can match both if $actual_len = test_len >= pat_len,
|
||||
// and if $actual_len > test_len. We can't advance.
|
||||
None
|
||||
@ -681,7 +681,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
(&TestKind::Range { .. }, _) => None,
|
||||
|
||||
(&TestKind::Eq { .. }, _) | (&TestKind::Len { .. }, _) => {
|
||||
(&TestKind::Eq { .. } | &TestKind::Len { .. }, _) => {
|
||||
// These are all binary tests.
|
||||
//
|
||||
// FIXME(#29623) we can be more clever here
|
||||
|
@ -46,8 +46,10 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {
|
||||
kind: hir::TraitItemKind::Fn(hir::FnSig { decl, .. }, hir::TraitFn::Provided(body_id)),
|
||||
..
|
||||
}) => (*body_id, decl.output.span()),
|
||||
Node::Item(hir::Item { kind: hir::ItemKind::Static(ty, _, body_id), .. })
|
||||
| Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, body_id), .. })
|
||||
Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Static(ty, _, body_id) | hir::ItemKind::Const(ty, body_id),
|
||||
..
|
||||
})
|
||||
| Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(ty, body_id), .. })
|
||||
| Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Const(ty, Some(body_id)),
|
||||
@ -394,8 +396,10 @@ impl BlockContext {
|
||||
Some(BlockFrame::SubExpr) => false,
|
||||
|
||||
// otherwise: use accumulated is_ignored state.
|
||||
Some(BlockFrame::TailExpr { tail_result_is_ignored: ignored })
|
||||
| Some(BlockFrame::Statement { ignores_expr_result: ignored }) => *ignored,
|
||||
Some(
|
||||
BlockFrame::TailExpr { tail_result_is_ignored: ignored }
|
||||
| BlockFrame::Statement { ignores_expr_result: ignored },
|
||||
) => *ignored,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -721,14 +721,16 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
Res::Def(DefKind::Struct, _)
|
||||
| Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
|
||||
| Res::Def(DefKind::Union, _)
|
||||
| Res::Def(DefKind::TyAlias, _)
|
||||
| Res::Def(DefKind::AssocTy, _)
|
||||
Res::Def(
|
||||
DefKind::Struct
|
||||
| DefKind::Ctor(CtorOf::Struct, ..)
|
||||
| DefKind::Union
|
||||
| DefKind::TyAlias
|
||||
| DefKind::AssocTy,
|
||||
_,
|
||||
)
|
||||
| Res::SelfTy(..)
|
||||
| Res::SelfCtor(..) => PatKind::Leaf { subpatterns },
|
||||
|
||||
_ => {
|
||||
let pattern_error = match res {
|
||||
Res::Def(DefKind::ConstParam, _) => PatternError::ConstParamInPattern(span),
|
||||
@ -765,7 +767,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
_ => false,
|
||||
};
|
||||
let kind = match res {
|
||||
Res::Def(DefKind::Const, def_id) | Res::Def(DefKind::AssocConst, def_id) => {
|
||||
Res::Def(DefKind::Const | DefKind::AssocConst, def_id) => {
|
||||
let substs = self.tables.node_substs(id);
|
||||
// Use `Reveal::All` here because patterns are always monomorphic even if their function isn't.
|
||||
match self.tcx.const_eval_resolve(
|
||||
|
@ -9,6 +9,7 @@
|
||||
#![feature(const_panic)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(bool_to_option)]
|
||||
#![feature(or_patterns)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -508,11 +508,11 @@ impl<'a> Parser<'a> {
|
||||
// `x == y == z`
|
||||
(BinOpKind::Eq, AssocOp::Equal) |
|
||||
// `x < y < z` and friends.
|
||||
(BinOpKind::Lt, AssocOp::Less) | (BinOpKind::Lt, AssocOp::LessEqual) |
|
||||
(BinOpKind::Le, AssocOp::LessEqual) | (BinOpKind::Le, AssocOp::Less) |
|
||||
(BinOpKind::Lt, AssocOp::Less | AssocOp::LessEqual) |
|
||||
(BinOpKind::Le, AssocOp::LessEqual | AssocOp::Less) |
|
||||
// `x > y > z` and friends.
|
||||
(BinOpKind::Gt, AssocOp::Greater) | (BinOpKind::Gt, AssocOp::GreaterEqual) |
|
||||
(BinOpKind::Ge, AssocOp::GreaterEqual) | (BinOpKind::Ge, AssocOp::Greater) => {
|
||||
(BinOpKind::Gt, AssocOp::Greater | AssocOp::GreaterEqual) |
|
||||
(BinOpKind::Ge, AssocOp::GreaterEqual | AssocOp::Greater) => {
|
||||
let expr_to_str = |e: &Expr| {
|
||||
self.span_to_snippet(e.span)
|
||||
.unwrap_or_else(|_| pprust::expr_to_string(&e))
|
||||
@ -526,8 +526,7 @@ impl<'a> Parser<'a> {
|
||||
false // Keep the current parse behavior, where the AST is `(x < y) < z`.
|
||||
}
|
||||
// `x == y < z`
|
||||
(BinOpKind::Eq, AssocOp::Less) | (BinOpKind::Eq, AssocOp::LessEqual) |
|
||||
(BinOpKind::Eq, AssocOp::Greater) | (BinOpKind::Eq, AssocOp::GreaterEqual) => {
|
||||
(BinOpKind::Eq, AssocOp::Less | AssocOp::LessEqual | AssocOp::Greater | AssocOp::GreaterEqual) => {
|
||||
// Consume `z`/outer-op-rhs.
|
||||
let snapshot = self.clone();
|
||||
match self.parse_expr() {
|
||||
@ -545,8 +544,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
// `x > y == z`
|
||||
(BinOpKind::Lt, AssocOp::Equal) | (BinOpKind::Le, AssocOp::Equal) |
|
||||
(BinOpKind::Gt, AssocOp::Equal) | (BinOpKind::Ge, AssocOp::Equal) => {
|
||||
(BinOpKind::Lt | BinOpKind::Le | BinOpKind::Gt | BinOpKind::Ge, AssocOp::Equal) => {
|
||||
let snapshot = self.clone();
|
||||
// At this point it is always valid to enclose the lhs in parentheses, no
|
||||
// further checks are necessary.
|
||||
|
@ -162,7 +162,7 @@ impl<'a> Parser<'a> {
|
||||
_ => false,
|
||||
});
|
||||
match (is_end_ahead, &self.token.kind) {
|
||||
(true, token::BinOp(token::Or)) | (true, token::OrOr) => {
|
||||
(true, token::BinOp(token::Or) | token::OrOr) => {
|
||||
self.ban_illegal_vert(lo, "trailing", "not allowed in an or-pattern");
|
||||
self.bump();
|
||||
true
|
||||
|
@ -89,8 +89,7 @@ impl CheckAttrVisitor<'tcx> {
|
||||
match target {
|
||||
Target::Fn
|
||||
| Target::Closure
|
||||
| Target::Method(MethodKind::Trait { body: true })
|
||||
| Target::Method(MethodKind::Inherent) => true,
|
||||
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
|
||||
Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => {
|
||||
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
|
||||
lint.build("`#[inline]` is ignored on function prototypes").emit()
|
||||
@ -202,8 +201,7 @@ impl CheckAttrVisitor<'tcx> {
|
||||
fn check_target_feature(&self, attr: &Attribute, span: &Span, target: Target) -> bool {
|
||||
match target {
|
||||
Target::Fn
|
||||
| Target::Method(MethodKind::Trait { body: true })
|
||||
| Target::Method(MethodKind::Inherent) => true,
|
||||
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
|
||||
_ => {
|
||||
self.tcx
|
||||
.sess
|
||||
|
@ -52,8 +52,9 @@ impl NonConstExpr {
|
||||
|
||||
Self::Loop(While)
|
||||
| Self::Loop(WhileLet)
|
||||
| Self::Match(WhileDesugar)
|
||||
| Self::Match(WhileLetDesugar) => &[sym::const_loop, sym::const_if_match],
|
||||
| Self::Match(WhileDesugar | WhileLetDesugar) => {
|
||||
&[sym::const_loop, sym::const_if_match]
|
||||
}
|
||||
|
||||
// A `for` loop's desugaring contains a call to `IntoIterator::into_iter`,
|
||||
// so they are not yet allowed with `#![feature(const_loop)]`.
|
||||
|
@ -24,13 +24,15 @@ use rustc_span::symbol::sym;
|
||||
// may need to be marked as live.
|
||||
fn should_explore(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
|
||||
match tcx.hir().find(hir_id) {
|
||||
Some(Node::Item(..))
|
||||
| Some(Node::ImplItem(..))
|
||||
| Some(Node::ForeignItem(..))
|
||||
| Some(Node::TraitItem(..))
|
||||
| Some(Node::Variant(..))
|
||||
| Some(Node::AnonConst(..))
|
||||
| Some(Node::Pat(..)) => true,
|
||||
Some(
|
||||
Node::Item(..)
|
||||
| Node::ImplItem(..)
|
||||
| Node::ForeignItem(..)
|
||||
| Node::TraitItem(..)
|
||||
| Node::Variant(..)
|
||||
| Node::AnonConst(..)
|
||||
| Node::Pat(..),
|
||||
) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -67,9 +69,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||
|
||||
fn handle_res(&mut self, res: Res) {
|
||||
match res {
|
||||
Res::Def(DefKind::Const, _)
|
||||
| Res::Def(DefKind::AssocConst, _)
|
||||
| Res::Def(DefKind::TyAlias, _) => {
|
||||
Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::TyAlias, _) => {
|
||||
self.check_def_id(res.def_id());
|
||||
}
|
||||
_ if self.in_pat => {}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![feature(nll)]
|
||||
#![feature(or_patterns)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -117,7 +117,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> {
|
||||
// If this path leads to a constant, then we need to
|
||||
// recurse into the constant to continue finding
|
||||
// items that are reachable.
|
||||
Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => {
|
||||
Res::Def(DefKind::Const | DefKind::AssocConst, _) => {
|
||||
self.worklist.push(hir_id);
|
||||
}
|
||||
|
||||
|
@ -565,8 +565,10 @@ fn resolve_local<'tcx>(
|
||||
PatKind::Box(ref subpat) => is_binding_pat(&subpat),
|
||||
|
||||
PatKind::Ref(_, _)
|
||||
| PatKind::Binding(hir::BindingAnnotation::Unannotated, ..)
|
||||
| PatKind::Binding(hir::BindingAnnotation::Mutable, ..)
|
||||
| PatKind::Binding(
|
||||
hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Mutable,
|
||||
..,
|
||||
)
|
||||
| PatKind::Wild
|
||||
| PatKind::Path(_)
|
||||
| PatKind::Lit(_)
|
||||
|
@ -870,9 +870,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||
let expansion = ExpnId::root(); // FIXME(jseyfried) intercrate hygiene
|
||||
// Record primary definitions.
|
||||
match res {
|
||||
Res::Def(kind @ DefKind::Mod, def_id)
|
||||
| Res::Def(kind @ DefKind::Enum, def_id)
|
||||
| Res::Def(kind @ DefKind::Trait, def_id) => {
|
||||
Res::Def(kind @ (DefKind::Mod | DefKind::Enum | DefKind::Trait), def_id) => {
|
||||
let module = self.r.new_module(
|
||||
parent,
|
||||
ModuleKind::Def(kind, def_id, ident.name),
|
||||
@ -882,30 +880,33 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||
);
|
||||
self.r.define(parent, ident, TypeNS, (module, vis, span, expansion));
|
||||
}
|
||||
Res::Def(DefKind::Struct, _)
|
||||
| Res::Def(DefKind::Union, _)
|
||||
| Res::Def(DefKind::Variant, _)
|
||||
| Res::Def(DefKind::TyAlias, _)
|
||||
| Res::Def(DefKind::ForeignTy, _)
|
||||
| Res::Def(DefKind::OpaqueTy, _)
|
||||
| Res::Def(DefKind::TraitAlias, _)
|
||||
| Res::Def(DefKind::AssocTy, _)
|
||||
| Res::Def(DefKind::AssocOpaqueTy, _)
|
||||
Res::Def(
|
||||
DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::Variant
|
||||
| DefKind::TyAlias
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy
|
||||
| DefKind::AssocOpaqueTy,
|
||||
_,
|
||||
)
|
||||
| Res::PrimTy(..)
|
||||
| Res::ToolMod => self.r.define(parent, ident, TypeNS, (res, vis, span, expansion)),
|
||||
Res::Def(DefKind::Fn, _)
|
||||
| Res::Def(DefKind::AssocFn, _)
|
||||
| Res::Def(DefKind::Static, _)
|
||||
| Res::Def(DefKind::Const, _)
|
||||
| Res::Def(DefKind::AssocConst, _)
|
||||
| Res::Def(DefKind::Ctor(..), _) => {
|
||||
self.r.define(parent, ident, ValueNS, (res, vis, span, expansion))
|
||||
}
|
||||
Res::Def(
|
||||
DefKind::Fn
|
||||
| DefKind::AssocFn
|
||||
| DefKind::Static
|
||||
| DefKind::Const
|
||||
| DefKind::AssocConst
|
||||
| DefKind::Ctor(..),
|
||||
_,
|
||||
) => self.r.define(parent, ident, ValueNS, (res, vis, span, expansion)),
|
||||
Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => {
|
||||
self.r.define(parent, ident, MacroNS, (res, vis, span, expansion))
|
||||
}
|
||||
Res::Def(DefKind::TyParam, _)
|
||||
| Res::Def(DefKind::ConstParam, _)
|
||||
Res::Def(DefKind::TyParam | DefKind::ConstParam, _)
|
||||
| Res::Local(..)
|
||||
| Res::SelfTy(..)
|
||||
| Res::SelfCtor(..)
|
||||
@ -914,7 +915,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||
// Record some extra data for better diagnostics.
|
||||
let cstore = self.r.cstore();
|
||||
match res {
|
||||
Res::Def(DefKind::Struct, def_id) | Res::Def(DefKind::Union, def_id) => {
|
||||
Res::Def(DefKind::Struct | DefKind::Union, def_id) => {
|
||||
let field_names = cstore.struct_field_names_untracked(def_id, self.r.session);
|
||||
self.insert_field_names(def_id, field_names);
|
||||
}
|
||||
|
@ -237,18 +237,21 @@ impl<'a> PathSource<'a> {
|
||||
crate fn is_expected(self, res: Res) -> bool {
|
||||
match self {
|
||||
PathSource::Type => match res {
|
||||
Res::Def(DefKind::Struct, _)
|
||||
| Res::Def(DefKind::Union, _)
|
||||
| Res::Def(DefKind::Enum, _)
|
||||
| Res::Def(DefKind::Trait, _)
|
||||
| Res::Def(DefKind::TraitAlias, _)
|
||||
| Res::Def(DefKind::TyAlias, _)
|
||||
| Res::Def(DefKind::AssocTy, _)
|
||||
Res::Def(
|
||||
DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::Enum
|
||||
| DefKind::Trait
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::TyAlias
|
||||
| DefKind::AssocTy
|
||||
| DefKind::TyParam
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ForeignTy,
|
||||
_,
|
||||
)
|
||||
| Res::PrimTy(..)
|
||||
| Res::Def(DefKind::TyParam, _)
|
||||
| Res::SelfTy(..)
|
||||
| Res::Def(DefKind::OpaqueTy, _)
|
||||
| Res::Def(DefKind::ForeignTy, _) => true,
|
||||
| Res::SelfTy(..) => true,
|
||||
_ => false,
|
||||
},
|
||||
PathSource::Trait(AliasPossibility::No) => match res {
|
||||
@ -256,27 +259,29 @@ impl<'a> PathSource<'a> {
|
||||
_ => false,
|
||||
},
|
||||
PathSource::Trait(AliasPossibility::Maybe) => match res {
|
||||
Res::Def(DefKind::Trait, _) => true,
|
||||
Res::Def(DefKind::TraitAlias, _) => true,
|
||||
Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => true,
|
||||
_ => false,
|
||||
},
|
||||
PathSource::Expr(..) => match res {
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Const), _)
|
||||
| Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
|
||||
| Res::Def(DefKind::Const, _)
|
||||
| Res::Def(DefKind::Static, _)
|
||||
Res::Def(
|
||||
DefKind::Ctor(_, CtorKind::Const | CtorKind::Fn)
|
||||
| DefKind::Const
|
||||
| DefKind::Static
|
||||
| DefKind::Fn
|
||||
| DefKind::AssocFn
|
||||
| DefKind::AssocConst
|
||||
| DefKind::ConstParam,
|
||||
_,
|
||||
)
|
||||
| Res::Local(..)
|
||||
| Res::Def(DefKind::Fn, _)
|
||||
| Res::Def(DefKind::AssocFn, _)
|
||||
| Res::Def(DefKind::AssocConst, _)
|
||||
| Res::SelfCtor(..)
|
||||
| Res::Def(DefKind::ConstParam, _) => true,
|
||||
| Res::SelfCtor(..) => true,
|
||||
_ => false,
|
||||
},
|
||||
PathSource::Pat => match res {
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Const), _)
|
||||
| Res::Def(DefKind::Const, _)
|
||||
| Res::Def(DefKind::AssocConst, _)
|
||||
Res::Def(
|
||||
DefKind::Ctor(_, CtorKind::Const) | DefKind::Const | DefKind::AssocConst,
|
||||
_,
|
||||
)
|
||||
| Res::SelfCtor(..) => true,
|
||||
_ => false,
|
||||
},
|
||||
@ -285,20 +290,19 @@ impl<'a> PathSource<'a> {
|
||||
_ => false,
|
||||
},
|
||||
PathSource::Struct => match res {
|
||||
Res::Def(DefKind::Struct, _)
|
||||
| Res::Def(DefKind::Union, _)
|
||||
| Res::Def(DefKind::Variant, _)
|
||||
| Res::Def(DefKind::TyAlias, _)
|
||||
| Res::Def(DefKind::AssocTy, _)
|
||||
Res::Def(
|
||||
DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::Variant
|
||||
| DefKind::TyAlias
|
||||
| DefKind::AssocTy,
|
||||
_,
|
||||
)
|
||||
| Res::SelfTy(..) => true,
|
||||
_ => false,
|
||||
},
|
||||
PathSource::TraitItem(ns) => match res {
|
||||
Res::Def(DefKind::AssocConst, _) | Res::Def(DefKind::AssocFn, _)
|
||||
if ns == ValueNS =>
|
||||
{
|
||||
true
|
||||
}
|
||||
Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) if ns == ValueNS => true,
|
||||
Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true,
|
||||
_ => false,
|
||||
},
|
||||
@ -316,8 +320,8 @@ impl<'a> PathSource<'a> {
|
||||
(PathSource::Struct, false) => error_code!(E0422),
|
||||
(PathSource::Expr(..), true) => error_code!(E0423),
|
||||
(PathSource::Expr(..), false) => error_code!(E0425),
|
||||
(PathSource::Pat, true) | (PathSource::TupleStruct, true) => error_code!(E0532),
|
||||
(PathSource::Pat, false) | (PathSource::TupleStruct, false) => error_code!(E0531),
|
||||
(PathSource::Pat | PathSource::TupleStruct, true) => error_code!(E0532),
|
||||
(PathSource::Pat | PathSource::TupleStruct, false) => error_code!(E0531),
|
||||
(PathSource::TraitItem(..), true) => error_code!(E0575),
|
||||
(PathSource::TraitItem(..), false) => error_code!(E0576),
|
||||
}
|
||||
@ -459,7 +463,7 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
||||
let rib_kind = match fn_kind {
|
||||
// Bail if there's no body.
|
||||
FnKind::Fn(.., None) => return visit::walk_fn(self, fn_kind, sp),
|
||||
FnKind::Fn(FnCtxt::Free, ..) | FnKind::Fn(FnCtxt::Foreign, ..) => FnItemRibKind,
|
||||
FnKind::Fn(FnCtxt::Free | FnCtxt::Foreign, ..) => FnItemRibKind,
|
||||
FnKind::Fn(FnCtxt::Assoc(_), ..) | FnKind::Closure(..) => NormalRibKind,
|
||||
};
|
||||
let previous_value = replace(&mut self.diagnostic_metadata.current_function, Some(sp));
|
||||
@ -2147,7 +2151,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||
return;
|
||||
}
|
||||
match binding.res() {
|
||||
Res::Def(DefKind::Trait, _) | Res::Def(DefKind::TraitAlias, _) => {
|
||||
Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
|
||||
collected_traits.push((name, binding))
|
||||
}
|
||||
_ => (),
|
||||
|
@ -123,10 +123,10 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
|
||||
.map(|snippet| snippet.ends_with(')'))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
Res::Def(DefKind::Ctor(..), _)
|
||||
| Res::Def(DefKind::AssocFn, _)
|
||||
| Res::Def(DefKind::Const, _)
|
||||
| Res::Def(DefKind::AssocConst, _)
|
||||
Res::Def(
|
||||
DefKind::Ctor(..) | DefKind::AssocFn | DefKind::Const | DefKind::AssocConst,
|
||||
_,
|
||||
)
|
||||
| Res::SelfCtor(_)
|
||||
| Res::PrimTy(_)
|
||||
| Res::Local(_) => true,
|
||||
@ -527,8 +527,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
(Res::Def(DefKind::Enum, def_id), PathSource::TupleStruct)
|
||||
| (Res::Def(DefKind::Enum, def_id), PathSource::Expr(..)) => {
|
||||
(Res::Def(DefKind::Enum, def_id), PathSource::TupleStruct | PathSource::Expr(..)) => {
|
||||
if let Some(variants) = self.collect_enum_variants(def_id) {
|
||||
if !variants.is_empty() {
|
||||
let msg = if variants.len() == 1 {
|
||||
@ -563,11 +562,13 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
|
||||
bad_struct_syntax_suggestion(def_id);
|
||||
}
|
||||
}
|
||||
(Res::Def(DefKind::Union, def_id), _)
|
||||
| (Res::Def(DefKind::Variant, def_id), _)
|
||||
| (Res::Def(DefKind::Ctor(_, CtorKind::Fictive), def_id), _)
|
||||
if ns == ValueNS =>
|
||||
{
|
||||
(
|
||||
Res::Def(
|
||||
DefKind::Union | DefKind::Variant | DefKind::Ctor(_, CtorKind::Fictive),
|
||||
def_id,
|
||||
),
|
||||
_,
|
||||
) if ns == ValueNS => {
|
||||
bad_struct_syntax_suggestion(def_id);
|
||||
}
|
||||
(Res::Def(DefKind::Ctor(_, CtorKind::Fn), def_id), _) if ns == ValueNS => {
|
||||
@ -580,9 +581,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
|
||||
err.span_label(span, fallback_label);
|
||||
err.note("can't use `Self` as a constructor, you must use the implemented struct");
|
||||
}
|
||||
(Res::Def(DefKind::TyAlias, _), _) | (Res::Def(DefKind::AssocTy, _), _)
|
||||
if ns == ValueNS =>
|
||||
{
|
||||
(Res::Def(DefKind::TyAlias | DefKind::AssocTy, _), _) if ns == ValueNS => {
|
||||
err.note("can't use a type alias as a constructor");
|
||||
}
|
||||
_ => return false,
|
||||
@ -618,7 +617,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
|
||||
// Look for a field with the same name in the current self_type.
|
||||
if let Some(resolution) = self.r.partial_res_map.get(&node_id) {
|
||||
match resolution.base_res() {
|
||||
Res::Def(DefKind::Struct, did) | Res::Def(DefKind::Union, did)
|
||||
Res::Def(DefKind::Struct | DefKind::Union, did)
|
||||
if resolution.unresolved_segments() == 0 =>
|
||||
{
|
||||
if let Some(field_names) = self.r.field_names.get(&did) {
|
||||
|
@ -1835,10 +1835,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
Region::Static
|
||||
| Region::EarlyBound(_, _, LifetimeDefOrigin::ExplicitOrElided)
|
||||
| Region::LateBound(_, _, LifetimeDefOrigin::ExplicitOrElided)
|
||||
| Region::EarlyBound(_, _, LifetimeDefOrigin::Error)
|
||||
| Region::LateBound(_, _, LifetimeDefOrigin::Error)
|
||||
| Region::EarlyBound(
|
||||
_,
|
||||
_,
|
||||
LifetimeDefOrigin::ExplicitOrElided | LifetimeDefOrigin::Error,
|
||||
)
|
||||
| Region::LateBound(
|
||||
_,
|
||||
_,
|
||||
LifetimeDefOrigin::ExplicitOrElided | LifetimeDefOrigin::Error,
|
||||
)
|
||||
| Region::LateBoundAnon(..)
|
||||
| Region::Free(..) => {}
|
||||
}
|
||||
@ -1898,15 +1904,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
let type_def_id = match res {
|
||||
Res::Def(DefKind::AssocTy, def_id) if depth == 1 => Some(parent_def_id(self, def_id)),
|
||||
Res::Def(DefKind::Variant, def_id) if depth == 0 => Some(parent_def_id(self, def_id)),
|
||||
Res::Def(DefKind::Struct, def_id)
|
||||
| Res::Def(DefKind::Union, def_id)
|
||||
| Res::Def(DefKind::Enum, def_id)
|
||||
| Res::Def(DefKind::TyAlias, def_id)
|
||||
| Res::Def(DefKind::Trait, def_id)
|
||||
if depth == 0 =>
|
||||
{
|
||||
Some(def_id)
|
||||
}
|
||||
Res::Def(
|
||||
DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::Enum
|
||||
| DefKind::TyAlias
|
||||
| DefKind::Trait,
|
||||
def_id,
|
||||
) if depth == 0 => Some(def_id),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
@ -2149,9 +2154,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
// Whitelist the types that unambiguously always
|
||||
// result in the same type constructor being used
|
||||
// (it can't differ between `Self` and `self`).
|
||||
Res::Def(DefKind::Struct, _)
|
||||
| Res::Def(DefKind::Union, _)
|
||||
| Res::Def(DefKind::Enum, _)
|
||||
Res::Def(DefKind::Struct | DefKind::Union | DefKind::Enum, _)
|
||||
| Res::PrimTy(_) => return res == path.res,
|
||||
_ => {}
|
||||
}
|
||||
@ -2844,8 +2847,9 @@ fn insert_late_bound_lifetimes(
|
||||
|
||||
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
|
||||
match ty.kind {
|
||||
hir::TyKind::Path(hir::QPath::Resolved(Some(_), _))
|
||||
| hir::TyKind::Path(hir::QPath::TypeRelative(..)) => {
|
||||
hir::TyKind::Path(
|
||||
hir::QPath::Resolved(Some(_), _) | hir::QPath::TypeRelative(..),
|
||||
) => {
|
||||
// ignore lifetimes appearing in associated type
|
||||
// projections, as they are not *constrained*
|
||||
// (defined above)
|
||||
|
@ -534,7 +534,7 @@ impl<'a> ModuleData<'a> {
|
||||
|
||||
fn nearest_item_scope(&'a self) -> Module<'a> {
|
||||
match self.kind {
|
||||
ModuleKind::Def(DefKind::Enum, ..) | ModuleKind::Def(DefKind::Trait, ..) => {
|
||||
ModuleKind::Def(DefKind::Enum | DefKind::Trait, ..) => {
|
||||
self.parent.expect("enum or trait module without a parent")
|
||||
}
|
||||
_ => self,
|
||||
@ -705,8 +705,10 @@ impl<'a> NameBinding<'a> {
|
||||
|
||||
fn is_variant(&self) -> bool {
|
||||
match self.kind {
|
||||
NameBindingKind::Res(Res::Def(DefKind::Variant, _), _)
|
||||
| NameBindingKind::Res(Res::Def(DefKind::Ctor(CtorOf::Variant, ..), _), _) => true,
|
||||
NameBindingKind::Res(
|
||||
Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..), _),
|
||||
_,
|
||||
) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -741,9 +743,7 @@ impl<'a> NameBinding<'a> {
|
||||
|
||||
fn is_importable(&self) -> bool {
|
||||
match self.res() {
|
||||
Res::Def(DefKind::AssocConst, _)
|
||||
| Res::Def(DefKind::AssocFn, _)
|
||||
| Res::Def(DefKind::AssocTy, _) => false,
|
||||
Res::Def(DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy, _) => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
@ -1539,8 +1539,9 @@ impl<'a> Resolver<'a> {
|
||||
let expn_data = expn_id.expn_data();
|
||||
match expn_data.kind {
|
||||
ExpnKind::Root
|
||||
| ExpnKind::Macro(MacroKind::Bang, _)
|
||||
| ExpnKind::Macro(MacroKind::Derive, _) => Scope::DeriveHelpersCompat,
|
||||
| ExpnKind::Macro(MacroKind::Bang | MacroKind::Derive, _) => {
|
||||
Scope::DeriveHelpersCompat
|
||||
}
|
||||
_ => Scope::DeriveHelpers(expn_data.parent),
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user