Auto merge of #81461 - JohnTitor:rollup-b0ij25f, r=JohnTitor
Rollup of 13 pull requests Successful merges: - #70904 (Stabilize `Seek::stream_position` (feature `seek_convenience`)) - #79951 (Refractor a few more types to `rustc_type_ir` ) - #80868 (Print failure message on all tests that should panic, but don't) - #81062 (Improve diagnostics for Precise Capture) - #81277 (Make more traits of the From/Into family diagnostic items) - #81284 (Make `-Z time-passes` less noisy) - #81379 (Improve URLs handling) - #81416 (Tweak suggestion for missing field in patterns) - #81426 (const_evaluatable: expand abstract consts in try_unify) - #81428 (compiletest: Add two more unit tests) - #81430 (add const_evaluatable_checked test) - #81433 (const_evaluatable: stop looking into type aliases) - #81445 (Update cargo) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
0e190206e2
95 changed files with 1928 additions and 733 deletions
11
Cargo.lock
11
Cargo.lock
|
@ -770,7 +770,7 @@ checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
|
|||
|
||||
[[package]]
|
||||
name = "crates-io"
|
||||
version = "0.31.1"
|
||||
version = "0.33.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"curl",
|
||||
|
@ -1337,9 +1337,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.13.14"
|
||||
version = "0.13.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "186dd99cc77576e58344ad614fa9bb27bad9d048f85de3ca850c1f4e8b048260"
|
||||
checksum = "1d250f5f82326884bd39c2853577e70a121775db76818ffa452ed1e80de12986"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
|
@ -1792,9 +1792,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
version = "0.12.16+1.1.0"
|
||||
version = "0.12.18+1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f91b2f931ee975a98155195be8cd82d02e8e029d7d793d2bac1b8181ac97020"
|
||||
checksum = "3da6a42da88fc37ee1ecda212ffa254c25713532980005d5f7c0b0fbe7e6e885"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
|
@ -4345,6 +4345,7 @@ dependencies = [
|
|||
"bitflags",
|
||||
"rustc_data_structures",
|
||||
"rustc_index",
|
||||
"rustc_macros",
|
||||
"rustc_serialize",
|
||||
]
|
||||
|
||||
|
|
|
@ -83,7 +83,6 @@ mod vtable;
|
|||
mod prelude {
|
||||
pub(crate) use std::convert::{TryFrom, TryInto};
|
||||
|
||||
pub(crate) use rustc_ast::ast::{FloatTy, IntTy, UintTy};
|
||||
pub(crate) use rustc_span::Span;
|
||||
|
||||
pub(crate) use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
|
@ -91,7 +90,7 @@ mod prelude {
|
|||
pub(crate) use rustc_middle::mir::{self, *};
|
||||
pub(crate) use rustc_middle::ty::layout::{self, TyAndLayout};
|
||||
pub(crate) use rustc_middle::ty::{
|
||||
self, FnSig, Instance, InstanceDef, ParamEnv, Ty, TyCtxt, TypeAndMut, TypeFoldable,
|
||||
self, FloatTy, FnSig, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut, TypeFoldable, UintTy,
|
||||
};
|
||||
pub(crate) use rustc_target::abi::{Abi, LayoutOf, Scalar, Size, VariantIdx};
|
||||
|
||||
|
|
|
@ -304,9 +304,8 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
lhs: Self::Value,
|
||||
rhs: Self::Value,
|
||||
) -> (Self::Value, Self::Value) {
|
||||
use rustc_ast::IntTy::*;
|
||||
use rustc_ast::UintTy::*;
|
||||
use rustc_middle::ty::{Int, Uint};
|
||||
use rustc_middle::ty::{IntTy::*, UintTy::*};
|
||||
|
||||
let new_kind = match ty.kind() {
|
||||
Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.pointer_width)),
|
||||
|
|
|
@ -18,7 +18,6 @@ use crate::llvm::debuginfo::{
|
|||
};
|
||||
use crate::value::Value;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_data_structures::const_cstr;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
|
@ -830,37 +829,37 @@ trait MsvcBasicName {
|
|||
fn msvc_basic_name(self) -> &'static str;
|
||||
}
|
||||
|
||||
impl MsvcBasicName for ast::IntTy {
|
||||
impl MsvcBasicName for ty::IntTy {
|
||||
fn msvc_basic_name(self) -> &'static str {
|
||||
match self {
|
||||
ast::IntTy::Isize => "ptrdiff_t",
|
||||
ast::IntTy::I8 => "__int8",
|
||||
ast::IntTy::I16 => "__int16",
|
||||
ast::IntTy::I32 => "__int32",
|
||||
ast::IntTy::I64 => "__int64",
|
||||
ast::IntTy::I128 => "__int128",
|
||||
ty::IntTy::Isize => "ptrdiff_t",
|
||||
ty::IntTy::I8 => "__int8",
|
||||
ty::IntTy::I16 => "__int16",
|
||||
ty::IntTy::I32 => "__int32",
|
||||
ty::IntTy::I64 => "__int64",
|
||||
ty::IntTy::I128 => "__int128",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MsvcBasicName for ast::UintTy {
|
||||
impl MsvcBasicName for ty::UintTy {
|
||||
fn msvc_basic_name(self) -> &'static str {
|
||||
match self {
|
||||
ast::UintTy::Usize => "size_t",
|
||||
ast::UintTy::U8 => "unsigned __int8",
|
||||
ast::UintTy::U16 => "unsigned __int16",
|
||||
ast::UintTy::U32 => "unsigned __int32",
|
||||
ast::UintTy::U64 => "unsigned __int64",
|
||||
ast::UintTy::U128 => "unsigned __int128",
|
||||
ty::UintTy::Usize => "size_t",
|
||||
ty::UintTy::U8 => "unsigned __int8",
|
||||
ty::UintTy::U16 => "unsigned __int16",
|
||||
ty::UintTy::U32 => "unsigned __int32",
|
||||
ty::UintTy::U64 => "unsigned __int64",
|
||||
ty::UintTy::U128 => "unsigned __int128",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MsvcBasicName for ast::FloatTy {
|
||||
impl MsvcBasicName for ty::FloatTy {
|
||||
fn msvc_basic_name(self) -> &'static str {
|
||||
match self {
|
||||
ast::FloatTy::F32 => "float",
|
||||
ast::FloatTy::F64 => "double",
|
||||
ty::FloatTy::F32 => "float",
|
||||
ty::FloatTy::F64 => "double",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,13 +7,12 @@ use crate::llvm;
|
|||
use crate::llvm::{Bool, False, True};
|
||||
use crate::type_of::LayoutLlvmExt;
|
||||
use crate::value::Value;
|
||||
use rustc_ast as ast;
|
||||
use rustc_codegen_ssa::common::TypeKind;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::layout::TyAndLayout;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_target::abi::call::{CastTarget, FnAbi, Reg};
|
||||
use rustc_target::abi::{AddressSpace, Align, Integer, Size};
|
||||
|
||||
|
@ -80,32 +79,32 @@ impl CodegenCx<'ll, 'tcx> {
|
|||
self.type_i8()
|
||||
}
|
||||
|
||||
crate fn type_int_from_ty(&self, t: ast::IntTy) -> &'ll Type {
|
||||
crate fn type_int_from_ty(&self, t: ty::IntTy) -> &'ll Type {
|
||||
match t {
|
||||
ast::IntTy::Isize => self.type_isize(),
|
||||
ast::IntTy::I8 => self.type_i8(),
|
||||
ast::IntTy::I16 => self.type_i16(),
|
||||
ast::IntTy::I32 => self.type_i32(),
|
||||
ast::IntTy::I64 => self.type_i64(),
|
||||
ast::IntTy::I128 => self.type_i128(),
|
||||
ty::IntTy::Isize => self.type_isize(),
|
||||
ty::IntTy::I8 => self.type_i8(),
|
||||
ty::IntTy::I16 => self.type_i16(),
|
||||
ty::IntTy::I32 => self.type_i32(),
|
||||
ty::IntTy::I64 => self.type_i64(),
|
||||
ty::IntTy::I128 => self.type_i128(),
|
||||
}
|
||||
}
|
||||
|
||||
crate fn type_uint_from_ty(&self, t: ast::UintTy) -> &'ll Type {
|
||||
crate fn type_uint_from_ty(&self, t: ty::UintTy) -> &'ll Type {
|
||||
match t {
|
||||
ast::UintTy::Usize => self.type_isize(),
|
||||
ast::UintTy::U8 => self.type_i8(),
|
||||
ast::UintTy::U16 => self.type_i16(),
|
||||
ast::UintTy::U32 => self.type_i32(),
|
||||
ast::UintTy::U64 => self.type_i64(),
|
||||
ast::UintTy::U128 => self.type_i128(),
|
||||
ty::UintTy::Usize => self.type_isize(),
|
||||
ty::UintTy::U8 => self.type_i8(),
|
||||
ty::UintTy::U16 => self.type_i16(),
|
||||
ty::UintTy::U32 => self.type_i32(),
|
||||
ty::UintTy::U64 => self.type_i64(),
|
||||
ty::UintTy::U128 => self.type_i128(),
|
||||
}
|
||||
}
|
||||
|
||||
crate fn type_float_from_ty(&self, t: ast::FloatTy) -> &'ll Type {
|
||||
crate fn type_float_from_ty(&self, t: ty::FloatTy) -> &'ll Type {
|
||||
match t {
|
||||
ast::FloatTy::F32 => self.type_f32(),
|
||||
ast::FloatTy::F64 => self.type_f64(),
|
||||
ty::FloatTy::F32 => self.type_f32(),
|
||||
ty::FloatTy::F64 => self.type_f64(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -875,20 +875,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
ty::Uint(_) => value.to_string(),
|
||||
ty::Int(int_ty) => {
|
||||
match int_ty.normalize(bx.tcx().sess.target.pointer_width) {
|
||||
ast::IntTy::I8 => (value as i8).to_string(),
|
||||
ast::IntTy::I16 => (value as i16).to_string(),
|
||||
ast::IntTy::I32 => (value as i32).to_string(),
|
||||
ast::IntTy::I64 => (value as i64).to_string(),
|
||||
ast::IntTy::I128 => (value as i128).to_string(),
|
||||
ast::IntTy::Isize => unreachable!(),
|
||||
ty::IntTy::I8 => (value as i8).to_string(),
|
||||
ty::IntTy::I16 => (value as i16).to_string(),
|
||||
ty::IntTy::I32 => (value as i32).to_string(),
|
||||
ty::IntTy::I64 => (value as i64).to_string(),
|
||||
ty::IntTy::I128 => (value as i128).to_string(),
|
||||
ty::IntTy::Isize => unreachable!(),
|
||||
}
|
||||
}
|
||||
ty::Float(ast::FloatTy::F32) => {
|
||||
f32::from_bits(value as u32).to_string()
|
||||
}
|
||||
ty::Float(ast::FloatTy::F64) => {
|
||||
f64::from_bits(value as u64).to_string()
|
||||
}
|
||||
ty::Float(ty::FloatTy::F32) => f32::from_bits(value as u32).to_string(),
|
||||
ty::Float(ty::FloatTy::F64) => f64::from_bits(value as u64).to_string(),
|
||||
_ => span_bug!(span, "asm const has bad type {}", ty),
|
||||
};
|
||||
InlineAsmOperandRef::Const { string }
|
||||
|
|
|
@ -929,7 +929,9 @@ pub struct ExtCtxt<'a> {
|
|||
pub force_mode: bool,
|
||||
pub expansions: FxHashMap<Span, Vec<String>>,
|
||||
/// Called directly after having parsed an external `mod foo;` in expansion.
|
||||
pub(super) extern_mod_loaded: Option<&'a dyn Fn(&ast::Crate)>,
|
||||
///
|
||||
/// `Ident` is the module name.
|
||||
pub(super) extern_mod_loaded: Option<&'a dyn Fn(&ast::Crate, Ident)>,
|
||||
}
|
||||
|
||||
impl<'a> ExtCtxt<'a> {
|
||||
|
@ -937,7 +939,7 @@ impl<'a> ExtCtxt<'a> {
|
|||
sess: &'a Session,
|
||||
ecfg: expand::ExpansionConfig<'a>,
|
||||
resolver: &'a mut dyn ResolverExpand,
|
||||
extern_mod_loaded: Option<&'a dyn Fn(&ast::Crate)>,
|
||||
extern_mod_loaded: Option<&'a dyn Fn(&ast::Crate, Ident)>,
|
||||
) -> ExtCtxt<'a> {
|
||||
ExtCtxt {
|
||||
sess,
|
||||
|
|
|
@ -1407,7 +1407,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
|||
proc_macros: vec![],
|
||||
};
|
||||
if let Some(extern_mod_loaded) = self.cx.extern_mod_loaded {
|
||||
extern_mod_loaded(&krate);
|
||||
extern_mod_loaded(&krate, ident);
|
||||
}
|
||||
|
||||
*old_mod = krate.module;
|
||||
|
|
|
@ -34,7 +34,6 @@ use super::{InferCtxt, MiscVariable, TypeTrace};
|
|||
|
||||
use crate::traits::{Obligation, PredicateObligations};
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::sso::SsoHashMap;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
|
@ -281,7 +280,7 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
|
|||
&self,
|
||||
vid_is_expected: bool,
|
||||
vid: ty::FloatVid,
|
||||
val: ast::FloatTy,
|
||||
val: ty::FloatTy,
|
||||
) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||
self.inner
|
||||
.borrow_mut()
|
||||
|
|
|
@ -33,7 +33,7 @@ use rustc_session::lint;
|
|||
use rustc_session::output::{filename_for_input, filename_for_metadata};
|
||||
use rustc_session::search_paths::PathKind;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::symbol::{Ident, Symbol};
|
||||
use rustc_span::{FileName, RealFileName};
|
||||
use rustc_trait_selection::traits;
|
||||
use rustc_typeck as typeck;
|
||||
|
@ -211,8 +211,13 @@ pub fn register_plugins<'a>(
|
|||
Ok((krate, lint_store))
|
||||
}
|
||||
|
||||
fn pre_expansion_lint(sess: &Session, lint_store: &LintStore, krate: &ast::Crate) {
|
||||
sess.time("pre_AST_expansion_lint_checks", || {
|
||||
fn pre_expansion_lint(
|
||||
sess: &Session,
|
||||
lint_store: &LintStore,
|
||||
krate: &ast::Crate,
|
||||
crate_name: &str,
|
||||
) {
|
||||
sess.prof.generic_activity_with_arg("pre_AST_expansion_lint_checks", crate_name).run(|| {
|
||||
rustc_lint::check_ast_crate(
|
||||
sess,
|
||||
lint_store,
|
||||
|
@ -233,7 +238,7 @@ fn configure_and_expand_inner<'a>(
|
|||
metadata_loader: &'a MetadataLoaderDyn,
|
||||
) -> Result<(ast::Crate, Resolver<'a>)> {
|
||||
tracing::trace!("configure_and_expand_inner");
|
||||
pre_expansion_lint(sess, lint_store, &krate);
|
||||
pre_expansion_lint(sess, lint_store, &krate, crate_name);
|
||||
|
||||
let mut resolver = Resolver::new(sess, &krate, crate_name, metadata_loader, &resolver_arenas);
|
||||
rustc_builtin_macros::register_builtin_macros(&mut resolver);
|
||||
|
@ -295,7 +300,9 @@ fn configure_and_expand_inner<'a>(
|
|||
..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string())
|
||||
};
|
||||
|
||||
let extern_mod_loaded = |k: &ast::Crate| pre_expansion_lint(sess, lint_store, k);
|
||||
let extern_mod_loaded = |k: &ast::Crate, ident: Ident| {
|
||||
pre_expansion_lint(sess, lint_store, k, &*ident.name.as_str())
|
||||
};
|
||||
let mut ecx = ExtCtxt::new(&sess, cfg, &mut resolver, Some(&extern_mod_loaded));
|
||||
|
||||
// Expand macros now!
|
||||
|
|
|
@ -168,25 +168,25 @@ fn lint_overflowing_range_endpoint<'tcx>(
|
|||
|
||||
// For `isize` & `usize`, be conservative with the warnings, so that the
|
||||
// warnings are consistent between 32- and 64-bit platforms.
|
||||
fn int_ty_range(int_ty: ast::IntTy) -> (i128, i128) {
|
||||
fn int_ty_range(int_ty: ty::IntTy) -> (i128, i128) {
|
||||
match int_ty {
|
||||
ast::IntTy::Isize => (i64::MIN.into(), i64::MAX.into()),
|
||||
ast::IntTy::I8 => (i8::MIN.into(), i8::MAX.into()),
|
||||
ast::IntTy::I16 => (i16::MIN.into(), i16::MAX.into()),
|
||||
ast::IntTy::I32 => (i32::MIN.into(), i32::MAX.into()),
|
||||
ast::IntTy::I64 => (i64::MIN.into(), i64::MAX.into()),
|
||||
ast::IntTy::I128 => (i128::MIN, i128::MAX),
|
||||
ty::IntTy::Isize => (i64::MIN.into(), i64::MAX.into()),
|
||||
ty::IntTy::I8 => (i8::MIN.into(), i8::MAX.into()),
|
||||
ty::IntTy::I16 => (i16::MIN.into(), i16::MAX.into()),
|
||||
ty::IntTy::I32 => (i32::MIN.into(), i32::MAX.into()),
|
||||
ty::IntTy::I64 => (i64::MIN.into(), i64::MAX.into()),
|
||||
ty::IntTy::I128 => (i128::MIN, i128::MAX),
|
||||
}
|
||||
}
|
||||
|
||||
fn uint_ty_range(uint_ty: ast::UintTy) -> (u128, u128) {
|
||||
fn uint_ty_range(uint_ty: ty::UintTy) -> (u128, u128) {
|
||||
let max = match uint_ty {
|
||||
ast::UintTy::Usize => u64::MAX.into(),
|
||||
ast::UintTy::U8 => u8::MAX.into(),
|
||||
ast::UintTy::U16 => u16::MAX.into(),
|
||||
ast::UintTy::U32 => u32::MAX.into(),
|
||||
ast::UintTy::U64 => u64::MAX.into(),
|
||||
ast::UintTy::U128 => u128::MAX,
|
||||
ty::UintTy::Usize => u64::MAX.into(),
|
||||
ty::UintTy::U8 => u8::MAX.into(),
|
||||
ty::UintTy::U16 => u16::MAX.into(),
|
||||
ty::UintTy::U32 => u32::MAX.into(),
|
||||
ty::UintTy::U64 => u64::MAX.into(),
|
||||
ty::UintTy::U128 => u128::MAX,
|
||||
};
|
||||
(0, max)
|
||||
}
|
||||
|
@ -258,8 +258,8 @@ fn report_bin_hex_error(
|
|||
//
|
||||
// No suggestion for: `isize`, `usize`.
|
||||
fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static str> {
|
||||
use rustc_ast::IntTy::*;
|
||||
use rustc_ast::UintTy::*;
|
||||
use ty::IntTy::*;
|
||||
use ty::UintTy::*;
|
||||
macro_rules! find_fit {
|
||||
($ty:expr, $val:expr, $negative:expr,
|
||||
$($type:ident => [$($utypes:expr),*] => [$($itypes:expr),*]),+) => {
|
||||
|
@ -302,7 +302,7 @@ fn lint_int_literal<'tcx>(
|
|||
type_limits: &TypeLimits,
|
||||
e: &'tcx hir::Expr<'tcx>,
|
||||
lit: &hir::Lit,
|
||||
t: ast::IntTy,
|
||||
t: ty::IntTy,
|
||||
v: u128,
|
||||
) {
|
||||
let int_type = t.normalize(cx.sess().target.pointer_width);
|
||||
|
@ -314,7 +314,14 @@ fn lint_int_literal<'tcx>(
|
|||
// avoiding use of -min to prevent overflow/panic
|
||||
if (negative && v > max + 1) || (!negative && v > max) {
|
||||
if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
|
||||
report_bin_hex_error(cx, e, attr::IntType::SignedInt(t), repr_str, v, negative);
|
||||
report_bin_hex_error(
|
||||
cx,
|
||||
e,
|
||||
attr::IntType::SignedInt(ty::ast_int_ty(t)),
|
||||
repr_str,
|
||||
v,
|
||||
negative,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -351,7 +358,7 @@ fn lint_uint_literal<'tcx>(
|
|||
cx: &LateContext<'tcx>,
|
||||
e: &'tcx hir::Expr<'tcx>,
|
||||
lit: &hir::Lit,
|
||||
t: ast::UintTy,
|
||||
t: ty::UintTy,
|
||||
) {
|
||||
let uint_type = t.normalize(cx.sess().target.pointer_width);
|
||||
let (min, max) = uint_ty_range(uint_type);
|
||||
|
@ -391,7 +398,14 @@ fn lint_uint_literal<'tcx>(
|
|||
}
|
||||
}
|
||||
if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
|
||||
report_bin_hex_error(cx, e, attr::IntType::UnsignedInt(t), repr_str, lit_val, false);
|
||||
report_bin_hex_error(
|
||||
cx,
|
||||
e,
|
||||
attr::IntType::UnsignedInt(ty::ast_uint_ty(t)),
|
||||
repr_str,
|
||||
lit_val,
|
||||
false,
|
||||
);
|
||||
return;
|
||||
}
|
||||
cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| {
|
||||
|
@ -430,8 +444,8 @@ fn lint_literal<'tcx>(
|
|||
ty::Float(t) => {
|
||||
let is_infinite = match lit.node {
|
||||
ast::LitKind::Float(v, _) => match t {
|
||||
ast::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite),
|
||||
ast::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite),
|
||||
ty::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite),
|
||||
ty::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite),
|
||||
},
|
||||
_ => bug!(),
|
||||
};
|
||||
|
@ -984,7 +998,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
help: Some("consider using `u32` or `libc::wchar_t` instead".into()),
|
||||
},
|
||||
|
||||
ty::Int(ast::IntTy::I128) | ty::Uint(ast::UintTy::U128) => FfiUnsafe {
|
||||
ty::Int(ty::IntTy::I128) | ty::Uint(ty::UintTy::U128) => FfiUnsafe {
|
||||
ty,
|
||||
reason: "128-bit integers don't currently have a known stable ABI".into(),
|
||||
help: None,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::ty::{self, FloatVarValue, InferConst, IntVarValue, Ty, TyCtxt};
|
||||
use crate::ty::{self, InferConst, Ty, TyCtxt};
|
||||
use rustc_data_structures::snapshot_vec;
|
||||
use rustc_data_structures::undo_log::UndoLogs;
|
||||
use rustc_data_structures::unify::{
|
||||
|
@ -15,36 +15,6 @@ pub trait ToType {
|
|||
fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
|
||||
}
|
||||
|
||||
/// Raw `TyVid` are used as the unification key for `sub_relations`;
|
||||
/// they carry no values.
|
||||
impl UnifyKey for ty::TyVid {
|
||||
type Value = ();
|
||||
fn index(&self) -> u32 {
|
||||
self.index
|
||||
}
|
||||
fn from_index(i: u32) -> ty::TyVid {
|
||||
ty::TyVid { index: i }
|
||||
}
|
||||
fn tag() -> &'static str {
|
||||
"TyVid"
|
||||
}
|
||||
}
|
||||
|
||||
impl UnifyKey for ty::IntVid {
|
||||
type Value = Option<IntVarValue>;
|
||||
fn index(&self) -> u32 {
|
||||
self.index
|
||||
}
|
||||
fn from_index(i: u32) -> ty::IntVid {
|
||||
ty::IntVid { index: i }
|
||||
}
|
||||
fn tag() -> &'static str {
|
||||
"IntVid"
|
||||
}
|
||||
}
|
||||
|
||||
impl EqUnifyValue for IntVarValue {}
|
||||
|
||||
#[derive(PartialEq, Copy, Clone, Debug)]
|
||||
pub struct RegionVidKey {
|
||||
/// The minimum region vid in the unification set. This is needed
|
||||
|
@ -80,7 +50,7 @@ impl UnifyKey for ty::RegionVid {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToType for IntVarValue {
|
||||
impl ToType for ty::IntVarValue {
|
||||
fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
match *self {
|
||||
ty::IntType(i) => tcx.mk_mach_int(i),
|
||||
|
@ -89,24 +59,7 @@ impl ToType for IntVarValue {
|
|||
}
|
||||
}
|
||||
|
||||
// Floating point type keys
|
||||
|
||||
impl UnifyKey for ty::FloatVid {
|
||||
type Value = Option<FloatVarValue>;
|
||||
fn index(&self) -> u32 {
|
||||
self.index
|
||||
}
|
||||
fn from_index(i: u32) -> ty::FloatVid {
|
||||
ty::FloatVid { index: i }
|
||||
}
|
||||
fn tag() -> &'static str {
|
||||
"FloatVid"
|
||||
}
|
||||
}
|
||||
|
||||
impl EqUnifyValue for FloatVarValue {}
|
||||
|
||||
impl ToType for FloatVarValue {
|
||||
impl ToType for ty::FloatVarValue {
|
||||
fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
tcx.mk_mach_float(self.0)
|
||||
}
|
||||
|
|
|
@ -3,13 +3,12 @@
|
|||
|
||||
use crate::ty::{self, Ty};
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_macros::HashStable;
|
||||
|
||||
/// Types that are represented as ints.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum IntTy {
|
||||
U(ast::UintTy),
|
||||
U(ty::UintTy),
|
||||
I,
|
||||
CEnum,
|
||||
Bool,
|
||||
|
|
|
@ -19,10 +19,10 @@ use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, Substs
|
|||
use crate::ty::TyKind::*;
|
||||
use crate::ty::{
|
||||
self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig, Const, ConstVid,
|
||||
DefIdTree, ExistentialPredicate, FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy,
|
||||
IntVar, IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind,
|
||||
ProjectionTy, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar,
|
||||
TyVid, TypeAndMut, Visibility,
|
||||
DefIdTree, ExistentialPredicate, FloatTy, FloatVar, FloatVid, GenericParamDefKind, InferConst,
|
||||
InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate,
|
||||
PredicateInner, PredicateKind, ProjectionTy, Region, RegionKind, ReprOptions,
|
||||
TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy, Visibility,
|
||||
};
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::expand::allocator::AllocatorKind;
|
||||
|
@ -839,20 +839,20 @@ impl<'tcx> CommonTypes<'tcx> {
|
|||
bool: mk(Bool),
|
||||
char: mk(Char),
|
||||
never: mk(Never),
|
||||
isize: mk(Int(ast::IntTy::Isize)),
|
||||
i8: mk(Int(ast::IntTy::I8)),
|
||||
i16: mk(Int(ast::IntTy::I16)),
|
||||
i32: mk(Int(ast::IntTy::I32)),
|
||||
i64: mk(Int(ast::IntTy::I64)),
|
||||
i128: mk(Int(ast::IntTy::I128)),
|
||||
usize: mk(Uint(ast::UintTy::Usize)),
|
||||
u8: mk(Uint(ast::UintTy::U8)),
|
||||
u16: mk(Uint(ast::UintTy::U16)),
|
||||
u32: mk(Uint(ast::UintTy::U32)),
|
||||
u64: mk(Uint(ast::UintTy::U64)),
|
||||
u128: mk(Uint(ast::UintTy::U128)),
|
||||
f32: mk(Float(ast::FloatTy::F32)),
|
||||
f64: mk(Float(ast::FloatTy::F64)),
|
||||
isize: mk(Int(ty::IntTy::Isize)),
|
||||
i8: mk(Int(ty::IntTy::I8)),
|
||||
i16: mk(Int(ty::IntTy::I16)),
|
||||
i32: mk(Int(ty::IntTy::I32)),
|
||||
i64: mk(Int(ty::IntTy::I64)),
|
||||
i128: mk(Int(ty::IntTy::I128)),
|
||||
usize: mk(Uint(ty::UintTy::Usize)),
|
||||
u8: mk(Uint(ty::UintTy::U8)),
|
||||
u16: mk(Uint(ty::UintTy::U16)),
|
||||
u32: mk(Uint(ty::UintTy::U32)),
|
||||
u64: mk(Uint(ty::UintTy::U64)),
|
||||
u128: mk(Uint(ty::UintTy::U128)),
|
||||
f32: mk(Float(ty::FloatTy::F32)),
|
||||
f64: mk(Float(ty::FloatTy::F64)),
|
||||
str_: mk(Str),
|
||||
self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
|
||||
|
||||
|
@ -2102,32 +2102,32 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
|
||||
}
|
||||
|
||||
pub fn mk_mach_int(self, tm: ast::IntTy) -> Ty<'tcx> {
|
||||
pub fn mk_mach_int(self, tm: IntTy) -> Ty<'tcx> {
|
||||
match tm {
|
||||
ast::IntTy::Isize => self.types.isize,
|
||||
ast::IntTy::I8 => self.types.i8,
|
||||
ast::IntTy::I16 => self.types.i16,
|
||||
ast::IntTy::I32 => self.types.i32,
|
||||
ast::IntTy::I64 => self.types.i64,
|
||||
ast::IntTy::I128 => self.types.i128,
|
||||
IntTy::Isize => self.types.isize,
|
||||
IntTy::I8 => self.types.i8,
|
||||
IntTy::I16 => self.types.i16,
|
||||
IntTy::I32 => self.types.i32,
|
||||
IntTy::I64 => self.types.i64,
|
||||
IntTy::I128 => self.types.i128,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mk_mach_uint(self, tm: ast::UintTy) -> Ty<'tcx> {
|
||||
pub fn mk_mach_uint(self, tm: UintTy) -> Ty<'tcx> {
|
||||
match tm {
|
||||
ast::UintTy::Usize => self.types.usize,
|
||||
ast::UintTy::U8 => self.types.u8,
|
||||
ast::UintTy::U16 => self.types.u16,
|
||||
ast::UintTy::U32 => self.types.u32,
|
||||
ast::UintTy::U64 => self.types.u64,
|
||||
ast::UintTy::U128 => self.types.u128,
|
||||
UintTy::Usize => self.types.usize,
|
||||
UintTy::U8 => self.types.u8,
|
||||
UintTy::U16 => self.types.u16,
|
||||
UintTy::U32 => self.types.u32,
|
||||
UintTy::U64 => self.types.u64,
|
||||
UintTy::U128 => self.types.u128,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mk_mach_float(self, tm: ast::FloatTy) -> Ty<'tcx> {
|
||||
pub fn mk_mach_float(self, tm: FloatTy) -> Ty<'tcx> {
|
||||
match tm {
|
||||
ast::FloatTy::F32 => self.types.f32,
|
||||
ast::FloatTy::F64 => self.types.f64,
|
||||
FloatTy::F32 => self.types.f32,
|
||||
FloatTy::F64 => self.types.f64,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
//! Diagnostics related methods for `TyS`.
|
||||
|
||||
use crate::ty::sty::InferTy;
|
||||
use crate::ty::TyKind::*;
|
||||
use crate::ty::{TyCtxt, TyS};
|
||||
use crate::ty::{InferTy, TyCtxt, TyS};
|
||||
use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::traits::{ObligationCause, ObligationCauseCode};
|
||||
use crate::ty::diagnostics::suggest_constraining_type_param;
|
||||
use crate::ty::{self, BoundRegionKind, Region, Ty, TyCtxt};
|
||||
use rustc_ast as ast;
|
||||
use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect};
|
||||
use rustc_errors::{pluralize, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
|
@ -48,7 +47,7 @@ pub enum TypeError<'tcx> {
|
|||
|
||||
Sorts(ExpectedFound<Ty<'tcx>>),
|
||||
IntMismatch(ExpectedFound<ty::IntVarValue>),
|
||||
FloatMismatch(ExpectedFound<ast::FloatTy>),
|
||||
FloatMismatch(ExpectedFound<ty::FloatTy>),
|
||||
Traits(ExpectedFound<DefId>),
|
||||
VariadicMismatch(ExpectedFound<bool>),
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::ich::StableHashingContext;
|
||||
use crate::ty::{self, Ty, TyCtxt};
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use std::fmt::Debug;
|
||||
|
@ -24,9 +23,9 @@ where
|
|||
{
|
||||
BoolSimplifiedType,
|
||||
CharSimplifiedType,
|
||||
IntSimplifiedType(ast::IntTy),
|
||||
UintSimplifiedType(ast::UintTy),
|
||||
FloatSimplifiedType(ast::FloatTy),
|
||||
IntSimplifiedType(ty::IntTy),
|
||||
UintSimplifiedType(ty::UintTy),
|
||||
FloatSimplifiedType(ty::FloatTy),
|
||||
AdtSimplifiedType(D),
|
||||
StrSimplifiedType,
|
||||
ArraySimplifiedType,
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::mir::{GeneratorLayout, GeneratorSavedLocal};
|
|||
use crate::ty::subst::Subst;
|
||||
use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable};
|
||||
|
||||
use rustc_ast::{self as ast, IntTy, UintTy};
|
||||
use rustc_ast as ast;
|
||||
use rustc_attr as attr;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_hir as hir;
|
||||
|
@ -30,6 +30,8 @@ use std::ops::Bound;
|
|||
pub trait IntegerExt {
|
||||
fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx>;
|
||||
fn from_attr<C: HasDataLayout>(cx: &C, ity: attr::IntType) -> Integer;
|
||||
fn from_int_ty<C: HasDataLayout>(cx: &C, ity: ty::IntTy) -> Integer;
|
||||
fn from_uint_ty<C: HasDataLayout>(cx: &C, uty: ty::UintTy) -> Integer;
|
||||
fn repr_discr<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
|
@ -60,17 +62,38 @@ impl IntegerExt for Integer {
|
|||
let dl = cx.data_layout();
|
||||
|
||||
match ity {
|
||||
attr::SignedInt(IntTy::I8) | attr::UnsignedInt(UintTy::U8) => I8,
|
||||
attr::SignedInt(IntTy::I16) | attr::UnsignedInt(UintTy::U16) => I16,
|
||||
attr::SignedInt(IntTy::I32) | attr::UnsignedInt(UintTy::U32) => I32,
|
||||
attr::SignedInt(IntTy::I64) | attr::UnsignedInt(UintTy::U64) => I64,
|
||||
attr::SignedInt(IntTy::I128) | attr::UnsignedInt(UintTy::U128) => I128,
|
||||
attr::SignedInt(IntTy::Isize) | attr::UnsignedInt(UintTy::Usize) => {
|
||||
attr::SignedInt(ast::IntTy::I8) | attr::UnsignedInt(ast::UintTy::U8) => I8,
|
||||
attr::SignedInt(ast::IntTy::I16) | attr::UnsignedInt(ast::UintTy::U16) => I16,
|
||||
attr::SignedInt(ast::IntTy::I32) | attr::UnsignedInt(ast::UintTy::U32) => I32,
|
||||
attr::SignedInt(ast::IntTy::I64) | attr::UnsignedInt(ast::UintTy::U64) => I64,
|
||||
attr::SignedInt(ast::IntTy::I128) | attr::UnsignedInt(ast::UintTy::U128) => I128,
|
||||
attr::SignedInt(ast::IntTy::Isize) | attr::UnsignedInt(ast::UintTy::Usize) => {
|
||||
dl.ptr_sized_integer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn from_int_ty<C: HasDataLayout>(cx: &C, ity: ty::IntTy) -> Integer {
|
||||
match ity {
|
||||
ty::IntTy::I8 => I8,
|
||||
ty::IntTy::I16 => I16,
|
||||
ty::IntTy::I32 => I32,
|
||||
ty::IntTy::I64 => I64,
|
||||
ty::IntTy::I128 => I128,
|
||||
ty::IntTy::Isize => cx.data_layout().ptr_sized_integer(),
|
||||
}
|
||||
}
|
||||
fn from_uint_ty<C: HasDataLayout>(cx: &C, ity: ty::UintTy) -> Integer {
|
||||
match ity {
|
||||
ty::UintTy::U8 => I8,
|
||||
ty::UintTy::U16 => I16,
|
||||
ty::UintTy::U32 => I32,
|
||||
ty::UintTy::U64 => I64,
|
||||
ty::UintTy::U128 => I128,
|
||||
ty::UintTy::Usize => cx.data_layout().ptr_sized_integer(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Finds the appropriate Integer type and signedness for the given
|
||||
/// signed discriminant range and `#[repr]` attribute.
|
||||
/// N.B.: `u128` values above `i128::MAX` will be treated as signed, but
|
||||
|
@ -487,11 +510,11 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
|||
self,
|
||||
Scalar { value: Int(I32, false), valid_range: 0..=0x10FFFF },
|
||||
)),
|
||||
ty::Int(ity) => scalar(Int(Integer::from_attr(dl, attr::SignedInt(ity)), true)),
|
||||
ty::Uint(ity) => scalar(Int(Integer::from_attr(dl, attr::UnsignedInt(ity)), false)),
|
||||
ty::Int(ity) => scalar(Int(Integer::from_int_ty(dl, ity), true)),
|
||||
ty::Uint(ity) => scalar(Int(Integer::from_uint_ty(dl, ity), false)),
|
||||
ty::Float(fty) => scalar(match fty {
|
||||
ast::FloatTy::F32 => F32,
|
||||
ast::FloatTy::F64 => F64,
|
||||
ty::FloatTy::F32 => F32,
|
||||
ty::FloatTy::F64 => F64,
|
||||
}),
|
||||
ty::FnPtr(_) => {
|
||||
let mut ptr = scalar_unit(Pointer);
|
||||
|
|
|
@ -65,7 +65,6 @@ use std::ptr;
|
|||
use std::str;
|
||||
|
||||
pub use self::sty::BoundRegionKind::*;
|
||||
pub use self::sty::InferTy::*;
|
||||
pub use self::sty::RegionKind;
|
||||
pub use self::sty::RegionKind::*;
|
||||
pub use self::sty::TyKind::*;
|
||||
|
@ -74,13 +73,14 @@ pub use self::sty::{BoundRegion, BoundRegionKind, EarlyBoundRegion, FreeRegion,
|
|||
pub use self::sty::{CanonicalPolyFnSig, FnSig, GenSig, PolyFnSig, PolyGenSig};
|
||||
pub use self::sty::{ClosureSubsts, GeneratorSubsts, TypeAndMut, UpvarSubsts};
|
||||
pub use self::sty::{ClosureSubstsParts, GeneratorSubstsParts};
|
||||
pub use self::sty::{ConstVid, FloatVid, IntVid, RegionVid, TyVid};
|
||||
pub use self::sty::{ExistentialPredicate, InferTy, ParamConst, ParamTy, ProjectionTy};
|
||||
pub use self::sty::{ConstVid, RegionVid};
|
||||
pub use self::sty::{ExistentialPredicate, ParamConst, ParamTy, ProjectionTy};
|
||||
pub use self::sty::{ExistentialProjection, PolyExistentialProjection};
|
||||
pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef};
|
||||
pub use self::sty::{PolyTraitRef, TraitRef, TyKind};
|
||||
pub use crate::ty::diagnostics::*;
|
||||
pub use rustc_type_ir::{DebruijnIndex, TypeFlags, INNERMOST};
|
||||
pub use rustc_type_ir::InferTy::*;
|
||||
pub use rustc_type_ir::*;
|
||||
|
||||
pub use self::binding::BindingMode;
|
||||
pub use self::binding::BindingMode::*;
|
||||
|
@ -421,14 +421,6 @@ impl Visibility {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, TyDecodable, TyEncodable, HashStable)]
|
||||
pub enum Variance {
|
||||
Covariant, // T<A> <: T<B> iff A <: B -- e.g., function return type
|
||||
Invariant, // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
|
||||
Contravariant, // T<A> <: T<B> iff B <: A -- e.g., function param type
|
||||
Bivariant, // T<A> <: T<B> -- e.g., unused type parameter
|
||||
}
|
||||
|
||||
/// The crate variances map is computed during typeck and contains the
|
||||
/// variance of every item in the local crate. You should not use it
|
||||
/// directly, because to do so will make your pass dependent on the
|
||||
|
@ -443,66 +435,6 @@ pub struct CrateVariancesMap<'tcx> {
|
|||
pub variances: FxHashMap<DefId, &'tcx [ty::Variance]>,
|
||||
}
|
||||
|
||||
impl Variance {
|
||||
/// `a.xform(b)` combines the variance of a context with the
|
||||
/// variance of a type with the following meaning. If we are in a
|
||||
/// context with variance `a`, and we encounter a type argument in
|
||||
/// a position with variance `b`, then `a.xform(b)` is the new
|
||||
/// variance with which the argument appears.
|
||||
///
|
||||
/// Example 1:
|
||||
///
|
||||
/// *mut Vec<i32>
|
||||
///
|
||||
/// Here, the "ambient" variance starts as covariant. `*mut T` is
|
||||
/// invariant with respect to `T`, so the variance in which the
|
||||
/// `Vec<i32>` appears is `Covariant.xform(Invariant)`, which
|
||||
/// yields `Invariant`. Now, the type `Vec<T>` is covariant with
|
||||
/// respect to its type argument `T`, and hence the variance of
|
||||
/// the `i32` here is `Invariant.xform(Covariant)`, which results
|
||||
/// (again) in `Invariant`.
|
||||
///
|
||||
/// Example 2:
|
||||
///
|
||||
/// fn(*const Vec<i32>, *mut Vec<i32)
|
||||
///
|
||||
/// The ambient variance is covariant. A `fn` type is
|
||||
/// contravariant with respect to its parameters, so the variance
|
||||
/// within which both pointer types appear is
|
||||
/// `Covariant.xform(Contravariant)`, or `Contravariant`. `*const
|
||||
/// T` is covariant with respect to `T`, so the variance within
|
||||
/// which the first `Vec<i32>` appears is
|
||||
/// `Contravariant.xform(Covariant)` or `Contravariant`. The same
|
||||
/// is true for its `i32` argument. In the `*mut T` case, the
|
||||
/// variance of `Vec<i32>` is `Contravariant.xform(Invariant)`,
|
||||
/// and hence the outermost type is `Invariant` with respect to
|
||||
/// `Vec<i32>` (and its `i32` argument).
|
||||
///
|
||||
/// Source: Figure 1 of "Taming the Wildcards:
|
||||
/// Combining Definition- and Use-Site Variance" published in PLDI'11.
|
||||
pub fn xform(self, v: ty::Variance) -> ty::Variance {
|
||||
match (self, v) {
|
||||
// Figure 1, column 1.
|
||||
(ty::Covariant, ty::Covariant) => ty::Covariant,
|
||||
(ty::Covariant, ty::Contravariant) => ty::Contravariant,
|
||||
(ty::Covariant, ty::Invariant) => ty::Invariant,
|
||||
(ty::Covariant, ty::Bivariant) => ty::Bivariant,
|
||||
|
||||
// Figure 1, column 2.
|
||||
(ty::Contravariant, ty::Covariant) => ty::Contravariant,
|
||||
(ty::Contravariant, ty::Contravariant) => ty::Covariant,
|
||||
(ty::Contravariant, ty::Invariant) => ty::Invariant,
|
||||
(ty::Contravariant, ty::Bivariant) => ty::Bivariant,
|
||||
|
||||
// Figure 1, column 3.
|
||||
(ty::Invariant, _) => ty::Invariant,
|
||||
|
||||
// Figure 1, column 4.
|
||||
(ty::Bivariant, _) => ty::Bivariant,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Contains information needed to resolve types and (in the future) look up
|
||||
// the types of AST nodes.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
|
@ -780,8 +712,20 @@ pub fn place_to_string_for_capture(tcx: TyCtxt<'tcx>, place: &HirPlace<'tcx>) ->
|
|||
pub struct CaptureInfo<'tcx> {
|
||||
/// Expr Id pointing to use that resulted in selecting the current capture kind
|
||||
///
|
||||
/// Eg:
|
||||
/// ```rust,no_run
|
||||
/// let mut t = (0,1);
|
||||
///
|
||||
/// let c = || {
|
||||
/// println!("{}",t); // L1
|
||||
/// t.1 = 4; // L2
|
||||
/// };
|
||||
/// ```
|
||||
/// `capture_kind_expr_id` will point to the use on L2 and `path_expr_id` will point to the
|
||||
/// use on L1.
|
||||
///
|
||||
/// If the user doesn't enable feature `capture_disjoint_fields` (RFC 2229) then, it is
|
||||
/// possible that we don't see the use of a particular place resulting in expr_id being
|
||||
/// possible that we don't see the use of a particular place resulting in capture_kind_expr_id being
|
||||
/// None. In such case we fallback on uvpars_mentioned for span.
|
||||
///
|
||||
/// Eg:
|
||||
|
@ -795,7 +739,12 @@ pub struct CaptureInfo<'tcx> {
|
|||
///
|
||||
/// In this example, if `capture_disjoint_fields` is **not** set, then x will be captured,
|
||||
/// but we won't see it being used during capture analysis, since it's essentially a discard.
|
||||
pub expr_id: Option<hir::HirId>,
|
||||
pub capture_kind_expr_id: Option<hir::HirId>,
|
||||
/// Expr Id pointing to use that resulted the corresponding place being captured
|
||||
///
|
||||
/// See `capture_kind_expr_id` for example.
|
||||
///
|
||||
pub path_expr_id: Option<hir::HirId>,
|
||||
|
||||
/// Capture mode that was selected
|
||||
pub capture_kind: UpvarCapture<'tcx>,
|
||||
|
@ -804,15 +753,6 @@ pub struct CaptureInfo<'tcx> {
|
|||
pub type UpvarListMap = FxHashMap<DefId, FxIndexMap<hir::HirId, UpvarId>>;
|
||||
pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub enum IntVarValue {
|
||||
IntType(ast::IntTy),
|
||||
UintType(ast::UintTy),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub struct FloatVarValue(pub ast::FloatTy);
|
||||
|
||||
impl ty::EarlyBoundRegion {
|
||||
/// Does this early bound region have a name? Early bound regions normally
|
||||
/// always have names except when using anonymous lifetimes (`'_`).
|
||||
|
@ -3122,6 +3062,57 @@ pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
|
|||
None
|
||||
}
|
||||
|
||||
pub fn int_ty(ity: ast::IntTy) -> IntTy {
|
||||
match ity {
|
||||
ast::IntTy::Isize => IntTy::Isize,
|
||||
ast::IntTy::I8 => IntTy::I8,
|
||||
ast::IntTy::I16 => IntTy::I16,
|
||||
ast::IntTy::I32 => IntTy::I32,
|
||||
ast::IntTy::I64 => IntTy::I64,
|
||||
ast::IntTy::I128 => IntTy::I128,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uint_ty(uty: ast::UintTy) -> UintTy {
|
||||
match uty {
|
||||
ast::UintTy::Usize => UintTy::Usize,
|
||||
ast::UintTy::U8 => UintTy::U8,
|
||||
ast::UintTy::U16 => UintTy::U16,
|
||||
ast::UintTy::U32 => UintTy::U32,
|
||||
ast::UintTy::U64 => UintTy::U64,
|
||||
ast::UintTy::U128 => UintTy::U128,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn float_ty(fty: ast::FloatTy) -> FloatTy {
|
||||
match fty {
|
||||
ast::FloatTy::F32 => FloatTy::F32,
|
||||
ast::FloatTy::F64 => FloatTy::F64,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ast_int_ty(ity: IntTy) -> ast::IntTy {
|
||||
match ity {
|
||||
IntTy::Isize => ast::IntTy::Isize,
|
||||
IntTy::I8 => ast::IntTy::I8,
|
||||
IntTy::I16 => ast::IntTy::I16,
|
||||
IntTy::I32 => ast::IntTy::I32,
|
||||
IntTy::I64 => ast::IntTy::I64,
|
||||
IntTy::I128 => ast::IntTy::I128,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ast_uint_ty(uty: UintTy) -> ast::UintTy {
|
||||
match uty {
|
||||
UintTy::Usize => ast::UintTy::Usize,
|
||||
UintTy::U8 => ast::UintTy::U8,
|
||||
UintTy::U16 => ast::UintTy::U16,
|
||||
UintTy::U32 => ast::UintTy::U32,
|
||||
UintTy::U64 => ast::UintTy::U64,
|
||||
UintTy::U128 => ast::UintTy::U128,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut ty::query::Providers) {
|
||||
context::provide(providers);
|
||||
erase_regions::provide(providers);
|
||||
|
|
|
@ -3,7 +3,6 @@ use crate::mir::interpret::{AllocId, ConstValue, GlobalAlloc, Pointer, Scalar};
|
|||
use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
|
||||
use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_apfloat::ieee::{Double, Single};
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{self, CtorKind, DefKind, Namespace};
|
||||
|
@ -557,14 +556,19 @@ pub trait PrettyPrinter<'tcx>:
|
|||
}
|
||||
ty::FnPtr(ref bare_fn) => p!(print(bare_fn)),
|
||||
ty::Infer(infer_ty) => {
|
||||
let verbose = self.tcx().sess.verbose();
|
||||
if let ty::TyVar(ty_vid) = infer_ty {
|
||||
if let Some(name) = self.infer_ty_name(ty_vid) {
|
||||
p!(write("{}", name))
|
||||
} else {
|
||||
p!(write("{}", infer_ty))
|
||||
if verbose {
|
||||
p!(write("{:?}", infer_ty))
|
||||
} else {
|
||||
p!(write("{}", infer_ty))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p!(write("{}", infer_ty))
|
||||
if verbose { p!(write("{:?}", infer_ty)) } else { p!(write("{}", infer_ty)) }
|
||||
}
|
||||
}
|
||||
ty::Error(_) => p!("[type error]"),
|
||||
|
@ -968,7 +972,7 @@ pub trait PrettyPrinter<'tcx>:
|
|||
ty::TyS {
|
||||
kind:
|
||||
ty::Array(
|
||||
ty::TyS { kind: ty::Uint(ast::UintTy::U8), .. },
|
||||
ty::TyS { kind: ty::Uint(ty::UintTy::U8), .. },
|
||||
ty::Const {
|
||||
val: ty::ConstKind::Value(ConstValue::Scalar(int)),
|
||||
..
|
||||
|
@ -997,10 +1001,10 @@ pub trait PrettyPrinter<'tcx>:
|
|||
(Scalar::Int(int), ty::Bool) if int == ScalarInt::FALSE => p!("false"),
|
||||
(Scalar::Int(int), ty::Bool) if int == ScalarInt::TRUE => p!("true"),
|
||||
// Float
|
||||
(Scalar::Int(int), ty::Float(ast::FloatTy::F32)) => {
|
||||
(Scalar::Int(int), ty::Float(ty::FloatTy::F32)) => {
|
||||
p!(write("{}f32", Single::try_from(int).unwrap()))
|
||||
}
|
||||
(Scalar::Int(int), ty::Float(ast::FloatTy::F64)) => {
|
||||
(Scalar::Int(int), ty::Float(ty::FloatTy::F64)) => {
|
||||
p!(write("{}f64", Double::try_from(int).unwrap()))
|
||||
}
|
||||
// Int
|
||||
|
@ -1246,7 +1250,7 @@ pub struct FmtPrinterData<'a, 'tcx, F> {
|
|||
|
||||
pub region_highlight_mode: RegionHighlightMode,
|
||||
|
||||
pub name_resolver: Option<Box<&'a dyn Fn(ty::sty::TyVid) -> Option<String>>>,
|
||||
pub name_resolver: Option<Box<&'a dyn Fn(ty::TyVid) -> Option<String>>>,
|
||||
}
|
||||
|
||||
impl<F> Deref for FmtPrinter<'a, 'tcx, F> {
|
||||
|
@ -2007,21 +2011,6 @@ define_print_and_forward_display! {
|
|||
p!("fn", pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
|
||||
}
|
||||
|
||||
ty::InferTy {
|
||||
if cx.tcx().sess.verbose() {
|
||||
p!(write("{:?}", self));
|
||||
return Ok(cx);
|
||||
}
|
||||
match *self {
|
||||
ty::TyVar(_) => p!("_"),
|
||||
ty::IntVar(_) => p!(write("{}", "{integer}")),
|
||||
ty::FloatVar(_) => p!(write("{}", "{float}")),
|
||||
ty::FreshTy(v) => p!(write("FreshTy({})", v)),
|
||||
ty::FreshIntTy(v) => p!(write("FreshIntTy({})", v)),
|
||||
ty::FreshFloatTy(v) => p!(write("FreshFloatTy({})", v))
|
||||
}
|
||||
}
|
||||
|
||||
ty::TraitRef<'tcx> {
|
||||
p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
|
||||
}
|
||||
|
|
|
@ -111,81 +111,24 @@ impl fmt::Debug for ty::FreeRegion {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ty::Variance {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(match *self {
|
||||
ty::Covariant => "+",
|
||||
ty::Contravariant => "-",
|
||||
ty::Invariant => "o",
|
||||
ty::Bivariant => "*",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ty::FnSig<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "({:?}; c_variadic: {})->{:?}", self.inputs(), self.c_variadic, self.output())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ty::TyVid {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "_#{}t", self.index)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "_#{}c", self.index)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ty::IntVid {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "_#{}i", self.index)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ty::FloatVid {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "_#{}f", self.index)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ty::RegionVid {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "'_#{}r", self.index())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ty::InferTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
ty::TyVar(ref v) => v.fmt(f),
|
||||
ty::IntVar(ref v) => v.fmt(f),
|
||||
ty::FloatVar(ref v) => v.fmt(f),
|
||||
ty::FreshTy(v) => write!(f, "FreshTy({:?})", v),
|
||||
ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
|
||||
ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ty::IntVarValue {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
ty::IntType(ref v) => v.fmt(f),
|
||||
ty::UintType(ref v) => v.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ty::FloatVarValue {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ty::TraitRef<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
with_no_trimmed_paths(|| fmt::Display::fmt(self, f))
|
||||
|
@ -274,7 +217,7 @@ TrivialTypeFoldableAndLiftImpls! {
|
|||
u64,
|
||||
String,
|
||||
crate::middle::region::Scope,
|
||||
::rustc_ast::FloatTy,
|
||||
crate::ty::FloatTy,
|
||||
::rustc_ast::InlineAsmOptions,
|
||||
::rustc_ast::InlineAsmTemplatePiece,
|
||||
::rustc_ast::NodeId,
|
||||
|
|
|
@ -2,17 +2,16 @@
|
|||
|
||||
#![allow(rustc::usage_of_ty_tykind)]
|
||||
|
||||
use self::InferTy::*;
|
||||
use self::TyKind::*;
|
||||
|
||||
use crate::infer::canonical::Canonical;
|
||||
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
|
||||
use crate::ty::InferTy::{self, *};
|
||||
use crate::ty::{
|
||||
self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable, WithConstness,
|
||||
};
|
||||
use crate::ty::{DelaySpanBugEmitted, List, ParamEnv, TyS};
|
||||
use polonius_engine::Atom;
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
|
@ -104,13 +103,13 @@ pub enum TyKind<'tcx> {
|
|||
Char,
|
||||
|
||||
/// A primitive signed integer type. For example, `i32`.
|
||||
Int(ast::IntTy),
|
||||
Int(ty::IntTy),
|
||||
|
||||
/// A primitive unsigned integer type. For example, `u32`.
|
||||
Uint(ast::UintTy),
|
||||
Uint(ty::UintTy),
|
||||
|
||||
/// A primitive floating-point type. For example, `f64`.
|
||||
Float(ast::FloatTy),
|
||||
Float(ty::FloatTy),
|
||||
|
||||
/// Algebraic data types (ADT). For example: structures, enumerations and unions.
|
||||
///
|
||||
|
@ -1426,12 +1425,6 @@ pub struct EarlyBoundRegion {
|
|||
pub name: Symbol,
|
||||
}
|
||||
|
||||
/// A **ty**pe **v**ariable **ID**.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
|
||||
pub struct TyVid {
|
||||
pub index: u32,
|
||||
}
|
||||
|
||||
/// A **`const`** **v**ariable **ID**.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
|
||||
pub struct ConstVid<'tcx> {
|
||||
|
@ -1439,18 +1432,6 @@ pub struct ConstVid<'tcx> {
|
|||
pub phantom: PhantomData<&'tcx ()>,
|
||||
}
|
||||
|
||||
/// An **int**egral (`u32`, `i32`, `usize`, etc.) type **v**ariable **ID**.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
|
||||
pub struct IntVid {
|
||||
pub index: u32,
|
||||
}
|
||||
|
||||
/// An **float**ing-point (`f32` or `f64`) type **v**ariable **ID**.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
|
||||
pub struct FloatVid {
|
||||
pub index: u32,
|
||||
}
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
/// A **region** (lifetime) **v**ariable **ID**.
|
||||
pub struct RegionVid {
|
||||
|
@ -1464,43 +1445,6 @@ impl Atom for RegionVid {
|
|||
}
|
||||
}
|
||||
|
||||
/// A placeholder for a type that hasn't been inferred yet.
|
||||
///
|
||||
/// E.g., if we have an empty array (`[]`), then we create a fresh
|
||||
/// type variable for the element type since we won't know until it's
|
||||
/// used what the element type is supposed to be.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable)]
|
||||
pub enum InferTy {
|
||||
/// A type variable.
|
||||
TyVar(TyVid),
|
||||
/// An integral type variable (`{integer}`).
|
||||
///
|
||||
/// These are created when the compiler sees an integer literal like
|
||||
/// `1` that could be several different types (`u8`, `i32`, `u32`, etc.).
|
||||
/// We don't know until it's used what type it's supposed to be, so
|
||||
/// we create a fresh type variable.
|
||||
IntVar(IntVid),
|
||||
/// A floating-point type variable (`{float}`).
|
||||
///
|
||||
/// These are created when the compiler sees an float literal like
|
||||
/// `1.0` that could be either an `f32` or an `f64`.
|
||||
/// We don't know until it's used what type it's supposed to be, so
|
||||
/// we create a fresh type variable.
|
||||
FloatVar(FloatVid),
|
||||
|
||||
/// A [`FreshTy`][Self::FreshTy] is one that is generated as a replacement
|
||||
/// for an unbound type variable. This is convenient for caching etc. See
|
||||
/// `rustc_infer::infer::freshen` for more details.
|
||||
///
|
||||
/// Compare with [`TyVar`][Self::TyVar].
|
||||
FreshTy(u32),
|
||||
/// Like [`FreshTy`][Self::FreshTy], but as a replacement for [`IntVar`][Self::IntVar].
|
||||
FreshIntTy(u32),
|
||||
/// Like [`FreshTy`][Self::FreshTy], but as a replacement for [`FloatVar`][Self::FloatVar].
|
||||
FreshFloatTy(u32),
|
||||
}
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
pub struct BoundVar { .. }
|
||||
}
|
||||
|
@ -1853,7 +1797,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
pub fn sequence_element_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
match self.kind() {
|
||||
Array(ty, _) | Slice(ty) => ty,
|
||||
Str => tcx.mk_mach_uint(ast::UintTy::U8),
|
||||
Str => tcx.mk_mach_uint(ty::UintTy::U8),
|
||||
_ => bug!("`sequence_element_type` called on non-sequence value: {}", self),
|
||||
}
|
||||
}
|
||||
|
@ -1993,7 +1937,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
|
||||
#[inline]
|
||||
pub fn is_ptr_sized_integral(&self) -> bool {
|
||||
matches!(self.kind(), Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize))
|
||||
matches!(self.kind(), Int(ty::IntTy::Isize) | Uint(ty::UintTy::Usize))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -2181,9 +2125,9 @@ impl<'tcx> TyS<'tcx> {
|
|||
pub fn to_opt_closure_kind(&self) -> Option<ty::ClosureKind> {
|
||||
match self.kind() {
|
||||
Int(int_ty) => match int_ty {
|
||||
ast::IntTy::I8 => Some(ty::ClosureKind::Fn),
|
||||
ast::IntTy::I16 => Some(ty::ClosureKind::FnMut),
|
||||
ast::IntTy::I32 => Some(ty::ClosureKind::FnOnce),
|
||||
ty::IntTy::I8 => Some(ty::ClosureKind::Fn),
|
||||
ty::IntTy::I16 => Some(ty::ClosureKind::FnMut),
|
||||
ty::IntTy::I32 => Some(ty::ClosureKind::FnOnce),
|
||||
_ => bug!("cannot convert type `{:?}` to a closure kind", self),
|
||||
},
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ impl<'tcx> fmt::Display for Discr<'tcx> {
|
|||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self.ty.kind() {
|
||||
ty::Int(ity) => {
|
||||
let size = ty::tls::with(|tcx| Integer::from_attr(&tcx, SignedInt(ity)).size());
|
||||
let size = ty::tls::with(|tcx| Integer::from_int_ty(&tcx, ity).size());
|
||||
let x = self.val;
|
||||
// sign extend the raw representation to be an i128
|
||||
let x = size.sign_extend(x) as i128;
|
||||
|
@ -59,8 +59,8 @@ fn unsigned_max(size: Size) -> u128 {
|
|||
|
||||
fn int_size_and_signed<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (Size, bool) {
|
||||
let (int, signed) = match *ty.kind() {
|
||||
Int(ity) => (Integer::from_attr(&tcx, SignedInt(ity)), true),
|
||||
Uint(uty) => (Integer::from_attr(&tcx, UnsignedInt(uty)), false),
|
||||
Int(ity) => (Integer::from_int_ty(&tcx, ity), true),
|
||||
Uint(uty) => (Integer::from_uint_ty(&tcx, uty), false),
|
||||
_ => bug!("non integer discriminant"),
|
||||
};
|
||||
(int.size(), signed)
|
||||
|
@ -642,8 +642,8 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
}
|
||||
ty::Char => Some(std::char::MAX as u128),
|
||||
ty::Float(fty) => Some(match fty {
|
||||
ast::FloatTy::F32 => rustc_apfloat::ieee::Single::INFINITY.to_bits(),
|
||||
ast::FloatTy::F64 => rustc_apfloat::ieee::Double::INFINITY.to_bits(),
|
||||
ty::FloatTy::F32 => rustc_apfloat::ieee::Single::INFINITY.to_bits(),
|
||||
ty::FloatTy::F64 => rustc_apfloat::ieee::Double::INFINITY.to_bits(),
|
||||
}),
|
||||
_ => None,
|
||||
};
|
||||
|
@ -661,8 +661,8 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
}
|
||||
ty::Char => Some(0),
|
||||
ty::Float(fty) => Some(match fty {
|
||||
ast::FloatTy::F32 => (-::rustc_apfloat::ieee::Single::INFINITY).to_bits(),
|
||||
ast::FloatTy::F64 => (-::rustc_apfloat::ieee::Double::INFINITY).to_bits(),
|
||||
ty::FloatTy::F32 => (-::rustc_apfloat::ieee::Single::INFINITY).to_bits(),
|
||||
ty::FloatTy::F64 => (-::rustc_apfloat::ieee::Double::INFINITY).to_bits(),
|
||||
}),
|
||||
_ => None,
|
||||
};
|
||||
|
|
|
@ -2,13 +2,11 @@ use std::convert::TryFrom;
|
|||
|
||||
use rustc_apfloat::ieee::{Double, Single};
|
||||
use rustc_apfloat::{Float, FloatConvert};
|
||||
use rustc_ast::FloatTy;
|
||||
use rustc_attr as attr;
|
||||
use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar};
|
||||
use rustc_middle::mir::CastKind;
|
||||
use rustc_middle::ty::adjustment::PointerCast;
|
||||
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
|
||||
use rustc_middle::ty::{self, Ty, TypeAndMut};
|
||||
use rustc_middle::ty::{self, FloatTy, Ty, TypeAndMut};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_target::abi::{Integer, LayoutOf, Variants};
|
||||
|
||||
|
@ -203,8 +201,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
match *cast_ty.kind() {
|
||||
Int(_) | Uint(_) | RawPtr(_) => {
|
||||
let size = match *cast_ty.kind() {
|
||||
Int(t) => Integer::from_attr(self, attr::IntType::SignedInt(t)).size(),
|
||||
Uint(t) => Integer::from_attr(self, attr::IntType::UnsignedInt(t)).size(),
|
||||
Int(t) => Integer::from_int_ty(self, t).size(),
|
||||
Uint(t) => Integer::from_uint_ty(self, t).size(),
|
||||
RawPtr(_) => self.pointer_size(),
|
||||
_ => bug!(),
|
||||
};
|
||||
|
@ -235,7 +233,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
match *dest_ty.kind() {
|
||||
// float -> uint
|
||||
Uint(t) => {
|
||||
let size = Integer::from_attr(self, attr::IntType::UnsignedInt(t)).size();
|
||||
let size = Integer::from_uint_ty(self, t).size();
|
||||
// `to_u128` is a saturating cast, which is what we need
|
||||
// (https://doc.rust-lang.org/nightly/nightly-rustc/rustc_apfloat/trait.Float.html#method.to_i128_r).
|
||||
let v = f.to_u128(size.bits_usize()).value;
|
||||
|
@ -244,7 +242,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
}
|
||||
// float -> int
|
||||
Int(t) => {
|
||||
let size = Integer::from_attr(self, attr::IntType::SignedInt(t)).size();
|
||||
let size = Integer::from_int_ty(self, t).size();
|
||||
// `to_i128` is a saturating cast, which is what we need
|
||||
// (https://doc.rust-lang.org/nightly/nightly-rustc/rustc_apfloat/trait.Float.html#method.to_i128_r).
|
||||
let v = f.to_i128(size.bits_usize()).value;
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use std::convert::TryFrom;
|
||||
|
||||
use rustc_apfloat::Float;
|
||||
use rustc_ast::FloatTy;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::interpret::{InterpResult, Scalar};
|
||||
use rustc_middle::ty::{self, layout::TyAndLayout, Ty};
|
||||
use rustc_middle::ty::{self, layout::TyAndLayout, FloatTy, Ty};
|
||||
use rustc_target::abi::LayoutOf;
|
||||
|
||||
use super::{ImmTy, Immediate, InterpCx, Machine, PlaceTy};
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
use crate::build::matches::{Ascription, Binding, Candidate, MatchPair};
|
||||
use crate::build::Builder;
|
||||
use crate::thir::{self, *};
|
||||
use rustc_attr::{SignedInt, UnsignedInt};
|
||||
use rustc_hir::RangeEnd;
|
||||
use rustc_middle::mir::Place;
|
||||
use rustc_middle::ty;
|
||||
|
@ -203,13 +202,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
(Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))), 0)
|
||||
}
|
||||
ty::Int(ity) => {
|
||||
let size = Integer::from_attr(&tcx, SignedInt(ity)).size();
|
||||
let size = Integer::from_int_ty(&tcx, ity).size();
|
||||
let max = size.truncate(u128::MAX);
|
||||
let bias = 1u128 << (size.bits() - 1);
|
||||
(Some((0, max, size)), bias)
|
||||
}
|
||||
ty::Uint(uty) => {
|
||||
let size = Integer::from_attr(&tcx, UnsignedInt(uty)).size();
|
||||
let size = Integer::from_uint_ty(&tcx, uty).size();
|
||||
let max = size.truncate(u128::MAX);
|
||||
(Some((0, max, size)), 0)
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ crate fn lit_to_const<'tcx>(
|
|||
let id = tcx.allocate_bytes(data);
|
||||
ConstValue::Scalar(Scalar::Ptr(id.into()))
|
||||
}
|
||||
(ast::LitKind::Byte(n), ty::Uint(ast::UintTy::U8)) => {
|
||||
(ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => {
|
||||
ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1)))
|
||||
}
|
||||
(ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => {
|
||||
|
@ -56,11 +56,11 @@ crate fn lit_to_const<'tcx>(
|
|||
Ok(ty::Const::from_value(tcx, lit, ty))
|
||||
}
|
||||
|
||||
fn parse_float<'tcx>(num: Symbol, fty: ast::FloatTy, neg: bool) -> Result<ConstValue<'tcx>, ()> {
|
||||
fn parse_float<'tcx>(num: Symbol, fty: ty::FloatTy, neg: bool) -> Result<ConstValue<'tcx>, ()> {
|
||||
let num = num.as_str();
|
||||
use rustc_apfloat::ieee::{Double, Single};
|
||||
let scalar = match fty {
|
||||
ast::FloatTy::F32 => {
|
||||
ty::FloatTy::F32 => {
|
||||
num.parse::<f32>().map_err(|_| ())?;
|
||||
let mut f = num.parse::<Single>().unwrap_or_else(|e| {
|
||||
panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
|
||||
|
@ -70,7 +70,7 @@ fn parse_float<'tcx>(num: Symbol, fty: ast::FloatTy, neg: bool) -> Result<ConstV
|
|||
}
|
||||
Scalar::from_f32(f)
|
||||
}
|
||||
ast::FloatTy::F64 => {
|
||||
ty::FloatTy::F64 => {
|
||||
num.parse::<f64>().map_err(|_| ())?;
|
||||
let mut f = num.parse::<Double>().unwrap_or_else(|e| {
|
||||
panic!("apfloat::ieee::Double failed to parse `{}`: {:?}", num, e)
|
||||
|
|
|
@ -52,7 +52,6 @@ use super::{FieldPat, Pat, PatKind, PatRange};
|
|||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_index::vec::Idx;
|
||||
|
||||
use rustc_attr::{SignedInt, UnsignedInt};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{HirId, RangeEnd};
|
||||
use rustc_middle::mir::interpret::ConstValue;
|
||||
|
@ -103,10 +102,10 @@ impl IntRange {
|
|||
ty::Bool => Some((Size::from_bytes(1), 0)),
|
||||
ty::Char => Some((Size::from_bytes(4), 0)),
|
||||
ty::Int(ity) => {
|
||||
let size = Integer::from_attr(&tcx, SignedInt(ity)).size();
|
||||
let size = Integer::from_int_ty(&tcx, ity).size();
|
||||
Some((size, 1u128 << (size.bits() as u128 - 1)))
|
||||
}
|
||||
ty::Uint(uty) => Some((Integer::from_attr(&tcx, UnsignedInt(uty)).size(), 0)),
|
||||
ty::Uint(uty) => Some((Integer::from_uint_ty(&tcx, uty).size(), 0)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -167,7 +166,7 @@ impl IntRange {
|
|||
fn signed_bias(tcx: TyCtxt<'_>, ty: Ty<'_>) -> u128 {
|
||||
match *ty.kind() {
|
||||
ty::Int(ity) => {
|
||||
let bits = Integer::from_attr(&tcx, SignedInt(ity)).size().bits() as u128;
|
||||
let bits = Integer::from_int_ty(&tcx, ity).size().bits() as u128;
|
||||
1u128 << (bits - 1)
|
||||
}
|
||||
_ => 0,
|
||||
|
@ -959,13 +958,13 @@ impl<'tcx> SplitWildcard<'tcx> {
|
|||
smallvec![NonExhaustive]
|
||||
}
|
||||
&ty::Int(ity) => {
|
||||
let bits = Integer::from_attr(&cx.tcx, SignedInt(ity)).size().bits() as u128;
|
||||
let bits = Integer::from_int_ty(&cx.tcx, ity).size().bits() as u128;
|
||||
let min = 1u128 << (bits - 1);
|
||||
let max = min - 1;
|
||||
smallvec![make_range(min, max)]
|
||||
}
|
||||
&ty::Uint(uty) => {
|
||||
let size = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size();
|
||||
let size = Integer::from_uint_ty(&cx.tcx, uty).size();
|
||||
let max = size.truncate(u128::MAX);
|
||||
smallvec![make_range(0, max)]
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ pub(crate) use self::check_match::check_match;
|
|||
|
||||
use crate::thir::util::UserAnnotatedTyHelpers;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_errors::struct_span_err;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
|
||||
|
@ -1069,20 +1068,19 @@ crate fn compare_const_vals<'tcx>(
|
|||
if let (Some(a), Some(b)) = (a_bits, b_bits) {
|
||||
use rustc_apfloat::Float;
|
||||
return match *ty.kind() {
|
||||
ty::Float(ast::FloatTy::F32) => {
|
||||
ty::Float(ty::FloatTy::F32) => {
|
||||
let l = rustc_apfloat::ieee::Single::from_bits(a);
|
||||
let r = rustc_apfloat::ieee::Single::from_bits(b);
|
||||
l.partial_cmp(&r)
|
||||
}
|
||||
ty::Float(ast::FloatTy::F64) => {
|
||||
ty::Float(ty::FloatTy::F64) => {
|
||||
let l = rustc_apfloat::ieee::Double::from_bits(a);
|
||||
let r = rustc_apfloat::ieee::Double::from_bits(b);
|
||||
l.partial_cmp(&r)
|
||||
}
|
||||
ty::Int(ity) => {
|
||||
use rustc_attr::SignedInt;
|
||||
use rustc_middle::ty::layout::IntegerExt;
|
||||
let size = rustc_target::abi::Integer::from_attr(&tcx, SignedInt(ity)).size();
|
||||
let size = rustc_target::abi::Integer::from_int_ty(&tcx, ity).size();
|
||||
let a = size.sign_extend(a);
|
||||
let b = size.sign_extend(b);
|
||||
Some((a as i128).cmp(&(b as i128)))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustc_ast::{FloatTy, InlineAsmTemplatePiece, IntTy, UintTy};
|
||||
use rustc_ast::InlineAsmTemplatePiece;
|
||||
use rustc_errors::struct_span_err;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
|
@ -7,7 +7,7 @@ use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
|||
use rustc_index::vec::Idx;
|
||||
use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, UintTy};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
|
||||
use rustc_target::abi::{Pointer, VariantIdx};
|
||||
|
|
|
@ -622,6 +622,7 @@ symbols! {
|
|||
intel,
|
||||
into_iter,
|
||||
into_result,
|
||||
into_trait,
|
||||
intra_doc_pointers,
|
||||
intrinsics,
|
||||
irrefutable_let_patterns,
|
||||
|
@ -1159,6 +1160,8 @@ symbols! {
|
|||
truncf32,
|
||||
truncf64,
|
||||
try_blocks,
|
||||
try_from_trait,
|
||||
try_into_trait,
|
||||
try_trait,
|
||||
tt,
|
||||
tuple,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use rustc_ast::{FloatTy, IntTy, UintTy};
|
||||
use rustc_data_structures::base_n;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_hir as hir;
|
||||
|
@ -6,7 +5,7 @@ use rustc_hir::def_id::{CrateNum, DefId};
|
|||
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
|
||||
use rustc_middle::ty::print::{Print, Printer};
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
|
||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_middle::ty::{self, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeFoldable, UintTy};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use std::fmt::Write;
|
||||
|
|
|
@ -609,9 +609,29 @@ where
|
|||
/// Tries to unify two abstract constants using structural equality.
|
||||
pub(super) fn try_unify<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
a: AbstractConst<'tcx>,
|
||||
b: AbstractConst<'tcx>,
|
||||
mut a: AbstractConst<'tcx>,
|
||||
mut b: AbstractConst<'tcx>,
|
||||
) -> bool {
|
||||
// We substitute generics repeatedly to allow AbstractConsts to unify where a
|
||||
// ConstKind::Unevalated could be turned into an AbstractConst that would unify e.g.
|
||||
// Param(N) should unify with Param(T), substs: [Unevaluated("T2", [Unevaluated("T3", [Param(N)])])]
|
||||
while let Node::Leaf(a_ct) = a.root() {
|
||||
let a_ct = a_ct.subst(tcx, a.substs);
|
||||
match AbstractConst::from_const(tcx, a_ct) {
|
||||
Ok(Some(a_act)) => a = a_act,
|
||||
Ok(None) => break,
|
||||
Err(_) => return true,
|
||||
}
|
||||
}
|
||||
while let Node::Leaf(b_ct) = b.root() {
|
||||
let b_ct = b_ct.subst(tcx, b.substs);
|
||||
match AbstractConst::from_const(tcx, b_ct) {
|
||||
Ok(Some(b_act)) => b = b_act,
|
||||
Ok(None) => break,
|
||||
Err(_) => return true,
|
||||
}
|
||||
}
|
||||
|
||||
match (a.root(), b.root()) {
|
||||
(Node::Leaf(a_ct), Node::Leaf(b_ct)) => {
|
||||
let a_ct = a_ct.subst(tcx, a.substs);
|
||||
|
@ -632,8 +652,6 @@ pub(super) fn try_unify<'tcx>(
|
|||
// we do not want to use `assert_eq!(a(), b())` to infer that `N` and `M` have to be `1`. This
|
||||
// means that we only allow inference variables if they are equal.
|
||||
(ty::ConstKind::Infer(a_val), ty::ConstKind::Infer(b_val)) => a_val == b_val,
|
||||
// We may want to instead recurse into unevaluated constants here. That may require some
|
||||
// care to prevent infinite recursion, so let's just ignore this for now.
|
||||
(
|
||||
ty::ConstKind::Unevaluated(a_def, a_substs, None),
|
||||
ty::ConstKind::Unevaluated(b_def, b_substs, None),
|
||||
|
|
|
@ -346,26 +346,26 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
(ty::Char, Scalar(Char)) => true,
|
||||
(ty::Int(ty1), Scalar(Int(ty2))) => matches!(
|
||||
(ty1, ty2),
|
||||
(ast::IntTy::Isize, chalk_ir::IntTy::Isize)
|
||||
| (ast::IntTy::I8, chalk_ir::IntTy::I8)
|
||||
| (ast::IntTy::I16, chalk_ir::IntTy::I16)
|
||||
| (ast::IntTy::I32, chalk_ir::IntTy::I32)
|
||||
| (ast::IntTy::I64, chalk_ir::IntTy::I64)
|
||||
| (ast::IntTy::I128, chalk_ir::IntTy::I128)
|
||||
(ty::IntTy::Isize, chalk_ir::IntTy::Isize)
|
||||
| (ty::IntTy::I8, chalk_ir::IntTy::I8)
|
||||
| (ty::IntTy::I16, chalk_ir::IntTy::I16)
|
||||
| (ty::IntTy::I32, chalk_ir::IntTy::I32)
|
||||
| (ty::IntTy::I64, chalk_ir::IntTy::I64)
|
||||
| (ty::IntTy::I128, chalk_ir::IntTy::I128)
|
||||
),
|
||||
(ty::Uint(ty1), Scalar(Uint(ty2))) => matches!(
|
||||
(ty1, ty2),
|
||||
(ast::UintTy::Usize, chalk_ir::UintTy::Usize)
|
||||
| (ast::UintTy::U8, chalk_ir::UintTy::U8)
|
||||
| (ast::UintTy::U16, chalk_ir::UintTy::U16)
|
||||
| (ast::UintTy::U32, chalk_ir::UintTy::U32)
|
||||
| (ast::UintTy::U64, chalk_ir::UintTy::U64)
|
||||
| (ast::UintTy::U128, chalk_ir::UintTy::U128)
|
||||
(ty::UintTy::Usize, chalk_ir::UintTy::Usize)
|
||||
| (ty::UintTy::U8, chalk_ir::UintTy::U8)
|
||||
| (ty::UintTy::U16, chalk_ir::UintTy::U16)
|
||||
| (ty::UintTy::U32, chalk_ir::UintTy::U32)
|
||||
| (ty::UintTy::U64, chalk_ir::UintTy::U64)
|
||||
| (ty::UintTy::U128, chalk_ir::UintTy::U128)
|
||||
),
|
||||
(ty::Float(ty1), Scalar(Float(ty2))) => matches!(
|
||||
(ty1, ty2),
|
||||
(ast::FloatTy::F32, chalk_ir::FloatTy::F32)
|
||||
| (ast::FloatTy::F64, chalk_ir::FloatTy::F64)
|
||||
(ty::FloatTy::F32, chalk_ir::FloatTy::F32)
|
||||
| (ty::FloatTy::F64, chalk_ir::FloatTy::F64)
|
||||
),
|
||||
(&ty::Tuple(substs), Tuple(len, _)) => substs.len() == *len,
|
||||
(&ty::Array(..), Array(..)) => true,
|
||||
|
|
|
@ -233,8 +233,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::AliasEq<RustInterner<'tcx>>>
|
|||
|
||||
impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
|
||||
fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::Ty<RustInterner<'tcx>> {
|
||||
use rustc_ast as ast;
|
||||
|
||||
let int = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Int(i));
|
||||
let uint = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(i));
|
||||
let float = |f| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Float(f));
|
||||
|
@ -243,24 +241,24 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
|
|||
ty::Bool => chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Bool),
|
||||
ty::Char => chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Char),
|
||||
ty::Int(ty) => match ty {
|
||||
ast::IntTy::Isize => int(chalk_ir::IntTy::Isize),
|
||||
ast::IntTy::I8 => int(chalk_ir::IntTy::I8),
|
||||
ast::IntTy::I16 => int(chalk_ir::IntTy::I16),
|
||||
ast::IntTy::I32 => int(chalk_ir::IntTy::I32),
|
||||
ast::IntTy::I64 => int(chalk_ir::IntTy::I64),
|
||||
ast::IntTy::I128 => int(chalk_ir::IntTy::I128),
|
||||
ty::IntTy::Isize => int(chalk_ir::IntTy::Isize),
|
||||
ty::IntTy::I8 => int(chalk_ir::IntTy::I8),
|
||||
ty::IntTy::I16 => int(chalk_ir::IntTy::I16),
|
||||
ty::IntTy::I32 => int(chalk_ir::IntTy::I32),
|
||||
ty::IntTy::I64 => int(chalk_ir::IntTy::I64),
|
||||
ty::IntTy::I128 => int(chalk_ir::IntTy::I128),
|
||||
},
|
||||
ty::Uint(ty) => match ty {
|
||||
ast::UintTy::Usize => uint(chalk_ir::UintTy::Usize),
|
||||
ast::UintTy::U8 => uint(chalk_ir::UintTy::U8),
|
||||
ast::UintTy::U16 => uint(chalk_ir::UintTy::U16),
|
||||
ast::UintTy::U32 => uint(chalk_ir::UintTy::U32),
|
||||
ast::UintTy::U64 => uint(chalk_ir::UintTy::U64),
|
||||
ast::UintTy::U128 => uint(chalk_ir::UintTy::U128),
|
||||
ty::UintTy::Usize => uint(chalk_ir::UintTy::Usize),
|
||||
ty::UintTy::U8 => uint(chalk_ir::UintTy::U8),
|
||||
ty::UintTy::U16 => uint(chalk_ir::UintTy::U16),
|
||||
ty::UintTy::U32 => uint(chalk_ir::UintTy::U32),
|
||||
ty::UintTy::U64 => uint(chalk_ir::UintTy::U64),
|
||||
ty::UintTy::U128 => uint(chalk_ir::UintTy::U128),
|
||||
},
|
||||
ty::Float(ty) => match ty {
|
||||
ast::FloatTy::F32 => float(chalk_ir::FloatTy::F32),
|
||||
ast::FloatTy::F64 => float(chalk_ir::FloatTy::F64),
|
||||
ty::FloatTy::F32 => float(chalk_ir::FloatTy::F32),
|
||||
ty::FloatTy::F64 => float(chalk_ir::FloatTy::F64),
|
||||
},
|
||||
ty::Adt(def, substs) => {
|
||||
chalk_ir::TyKind::Adt(chalk_ir::AdtId(def), substs.lower_into(interner))
|
||||
|
@ -347,24 +345,24 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> {
|
|||
chalk_ir::Scalar::Bool => ty::Bool,
|
||||
chalk_ir::Scalar::Char => ty::Char,
|
||||
chalk_ir::Scalar::Int(int_ty) => match int_ty {
|
||||
chalk_ir::IntTy::Isize => ty::Int(ast::IntTy::Isize),
|
||||
chalk_ir::IntTy::I8 => ty::Int(ast::IntTy::I8),
|
||||
chalk_ir::IntTy::I16 => ty::Int(ast::IntTy::I16),
|
||||
chalk_ir::IntTy::I32 => ty::Int(ast::IntTy::I32),
|
||||
chalk_ir::IntTy::I64 => ty::Int(ast::IntTy::I64),
|
||||
chalk_ir::IntTy::I128 => ty::Int(ast::IntTy::I128),
|
||||
chalk_ir::IntTy::Isize => ty::Int(ty::IntTy::Isize),
|
||||
chalk_ir::IntTy::I8 => ty::Int(ty::IntTy::I8),
|
||||
chalk_ir::IntTy::I16 => ty::Int(ty::IntTy::I16),
|
||||
chalk_ir::IntTy::I32 => ty::Int(ty::IntTy::I32),
|
||||
chalk_ir::IntTy::I64 => ty::Int(ty::IntTy::I64),
|
||||
chalk_ir::IntTy::I128 => ty::Int(ty::IntTy::I128),
|
||||
},
|
||||
chalk_ir::Scalar::Uint(int_ty) => match int_ty {
|
||||
chalk_ir::UintTy::Usize => ty::Uint(ast::UintTy::Usize),
|
||||
chalk_ir::UintTy::U8 => ty::Uint(ast::UintTy::U8),
|
||||
chalk_ir::UintTy::U16 => ty::Uint(ast::UintTy::U16),
|
||||
chalk_ir::UintTy::U32 => ty::Uint(ast::UintTy::U32),
|
||||
chalk_ir::UintTy::U64 => ty::Uint(ast::UintTy::U64),
|
||||
chalk_ir::UintTy::U128 => ty::Uint(ast::UintTy::U128),
|
||||
chalk_ir::UintTy::Usize => ty::Uint(ty::UintTy::Usize),
|
||||
chalk_ir::UintTy::U8 => ty::Uint(ty::UintTy::U8),
|
||||
chalk_ir::UintTy::U16 => ty::Uint(ty::UintTy::U16),
|
||||
chalk_ir::UintTy::U32 => ty::Uint(ty::UintTy::U32),
|
||||
chalk_ir::UintTy::U64 => ty::Uint(ty::UintTy::U64),
|
||||
chalk_ir::UintTy::U128 => ty::Uint(ty::UintTy::U128),
|
||||
},
|
||||
chalk_ir::Scalar::Float(float_ty) => match float_ty {
|
||||
chalk_ir::FloatTy::F32 => ty::Float(ast::FloatTy::F32),
|
||||
chalk_ir::FloatTy::F64 => ty::Float(ast::FloatTy::F64),
|
||||
chalk_ir::FloatTy::F32 => ty::Float(ty::FloatTy::F32),
|
||||
chalk_ir::FloatTy::F64 => ty::Float(ty::FloatTy::F64),
|
||||
},
|
||||
},
|
||||
TyKind::Array(ty, c) => {
|
||||
|
|
|
@ -12,3 +12,4 @@ bitflags = "1.2.1"
|
|||
rustc_index = { path = "../rustc_index" }
|
||||
rustc_serialize = { path = "../rustc_serialize" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
|
|
|
@ -4,8 +4,13 @@
|
|||
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
#[macro_use]
|
||||
extern crate rustc_macros;
|
||||
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::unify::{EqUnifyValue, UnifyKey};
|
||||
use std::fmt;
|
||||
use std::mem::discriminant;
|
||||
|
||||
bitflags! {
|
||||
/// Flags that we track on types. These flags are propagated upwards
|
||||
|
@ -197,8 +202,409 @@ impl DebruijnIndex {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
#[derive(Encodable, Decodable)]
|
||||
pub enum IntTy {
|
||||
Isize,
|
||||
I8,
|
||||
I16,
|
||||
I32,
|
||||
I64,
|
||||
I128,
|
||||
}
|
||||
|
||||
impl IntTy {
|
||||
pub fn name_str(&self) -> &'static str {
|
||||
match *self {
|
||||
IntTy::Isize => "isize",
|
||||
IntTy::I8 => "i8",
|
||||
IntTy::I16 => "i16",
|
||||
IntTy::I32 => "i32",
|
||||
IntTy::I64 => "i64",
|
||||
IntTy::I128 => "i128",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bit_width(&self) -> Option<u64> {
|
||||
Some(match *self {
|
||||
IntTy::Isize => return None,
|
||||
IntTy::I8 => 8,
|
||||
IntTy::I16 => 16,
|
||||
IntTy::I32 => 32,
|
||||
IntTy::I64 => 64,
|
||||
IntTy::I128 => 128,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn normalize(&self, target_width: u32) -> Self {
|
||||
match self {
|
||||
IntTy::Isize => match target_width {
|
||||
16 => IntTy::I16,
|
||||
32 => IntTy::I32,
|
||||
64 => IntTy::I64,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
_ => *self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
|
||||
#[derive(Encodable, Decodable)]
|
||||
pub enum UintTy {
|
||||
Usize,
|
||||
U8,
|
||||
U16,
|
||||
U32,
|
||||
U64,
|
||||
U128,
|
||||
}
|
||||
|
||||
impl UintTy {
|
||||
pub fn name_str(&self) -> &'static str {
|
||||
match *self {
|
||||
UintTy::Usize => "usize",
|
||||
UintTy::U8 => "u8",
|
||||
UintTy::U16 => "u16",
|
||||
UintTy::U32 => "u32",
|
||||
UintTy::U64 => "u64",
|
||||
UintTy::U128 => "u128",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bit_width(&self) -> Option<u64> {
|
||||
Some(match *self {
|
||||
UintTy::Usize => return None,
|
||||
UintTy::U8 => 8,
|
||||
UintTy::U16 => 16,
|
||||
UintTy::U32 => 32,
|
||||
UintTy::U64 => 64,
|
||||
UintTy::U128 => 128,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn normalize(&self, target_width: u32) -> Self {
|
||||
match self {
|
||||
UintTy::Usize => match target_width {
|
||||
16 => UintTy::U16,
|
||||
32 => UintTy::U32,
|
||||
64 => UintTy::U64,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
_ => *self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
#[derive(Encodable, Decodable)]
|
||||
pub enum FloatTy {
|
||||
F32,
|
||||
F64,
|
||||
}
|
||||
|
||||
impl FloatTy {
|
||||
pub fn name_str(self) -> &'static str {
|
||||
match self {
|
||||
FloatTy::F32 => "f32",
|
||||
FloatTy::F64 => "f64",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bit_width(self) -> u64 {
|
||||
match self {
|
||||
FloatTy::F32 => 32,
|
||||
FloatTy::F64 => 64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub enum IntVarValue {
|
||||
IntType(IntTy),
|
||||
UintType(UintTy),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub struct FloatVarValue(pub FloatTy);
|
||||
|
||||
/// A **ty**pe **v**ariable **ID**.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
|
||||
pub struct TyVid {
|
||||
pub index: u32,
|
||||
}
|
||||
|
||||
/// An **int**egral (`u32`, `i32`, `usize`, etc.) type **v**ariable **ID**.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
|
||||
pub struct IntVid {
|
||||
pub index: u32,
|
||||
}
|
||||
|
||||
/// An **float**ing-point (`f32` or `f64`) type **v**ariable **ID**.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
|
||||
pub struct FloatVid {
|
||||
pub index: u32,
|
||||
}
|
||||
|
||||
/// A placeholder for a type that hasn't been inferred yet.
|
||||
///
|
||||
/// E.g., if we have an empty array (`[]`), then we create a fresh
|
||||
/// type variable for the element type since we won't know until it's
|
||||
/// used what the element type is supposed to be.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
|
||||
pub enum InferTy {
|
||||
/// A type variable.
|
||||
TyVar(TyVid),
|
||||
/// An integral type variable (`{integer}`).
|
||||
///
|
||||
/// These are created when the compiler sees an integer literal like
|
||||
/// `1` that could be several different types (`u8`, `i32`, `u32`, etc.).
|
||||
/// We don't know until it's used what type it's supposed to be, so
|
||||
/// we create a fresh type variable.
|
||||
IntVar(IntVid),
|
||||
/// A floating-point type variable (`{float}`).
|
||||
///
|
||||
/// These are created when the compiler sees an float literal like
|
||||
/// `1.0` that could be either an `f32` or an `f64`.
|
||||
/// We don't know until it's used what type it's supposed to be, so
|
||||
/// we create a fresh type variable.
|
||||
FloatVar(FloatVid),
|
||||
|
||||
/// A [`FreshTy`][Self::FreshTy] is one that is generated as a replacement
|
||||
/// for an unbound type variable. This is convenient for caching etc. See
|
||||
/// `rustc_infer::infer::freshen` for more details.
|
||||
///
|
||||
/// Compare with [`TyVar`][Self::TyVar].
|
||||
FreshTy(u32),
|
||||
/// Like [`FreshTy`][Self::FreshTy], but as a replacement for [`IntVar`][Self::IntVar].
|
||||
FreshIntTy(u32),
|
||||
/// Like [`FreshTy`][Self::FreshTy], but as a replacement for [`FloatVar`][Self::FloatVar].
|
||||
FreshFloatTy(u32),
|
||||
}
|
||||
|
||||
/// Raw `TyVid` are used as the unification key for `sub_relations`;
|
||||
/// they carry no values.
|
||||
impl UnifyKey for TyVid {
|
||||
type Value = ();
|
||||
fn index(&self) -> u32 {
|
||||
self.index
|
||||
}
|
||||
fn from_index(i: u32) -> TyVid {
|
||||
TyVid { index: i }
|
||||
}
|
||||
fn tag() -> &'static str {
|
||||
"TyVid"
|
||||
}
|
||||
}
|
||||
|
||||
impl EqUnifyValue for IntVarValue {}
|
||||
|
||||
impl UnifyKey for IntVid {
|
||||
type Value = Option<IntVarValue>;
|
||||
fn index(&self) -> u32 {
|
||||
self.index
|
||||
}
|
||||
fn from_index(i: u32) -> IntVid {
|
||||
IntVid { index: i }
|
||||
}
|
||||
fn tag() -> &'static str {
|
||||
"IntVid"
|
||||
}
|
||||
}
|
||||
|
||||
impl EqUnifyValue for FloatVarValue {}
|
||||
|
||||
impl UnifyKey for FloatVid {
|
||||
type Value = Option<FloatVarValue>;
|
||||
fn index(&self) -> u32 {
|
||||
self.index
|
||||
}
|
||||
fn from_index(i: u32) -> FloatVid {
|
||||
FloatVid { index: i }
|
||||
}
|
||||
fn tag() -> &'static str {
|
||||
"FloatVid"
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Decodable, Encodable)]
|
||||
pub enum Variance {
|
||||
Covariant, // T<A> <: T<B> iff A <: B -- e.g., function return type
|
||||
Invariant, // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
|
||||
Contravariant, // T<A> <: T<B> iff B <: A -- e.g., function param type
|
||||
Bivariant, // T<A> <: T<B> -- e.g., unused type parameter
|
||||
}
|
||||
|
||||
impl Variance {
|
||||
/// `a.xform(b)` combines the variance of a context with the
|
||||
/// variance of a type with the following meaning. If we are in a
|
||||
/// context with variance `a`, and we encounter a type argument in
|
||||
/// a position with variance `b`, then `a.xform(b)` is the new
|
||||
/// variance with which the argument appears.
|
||||
///
|
||||
/// Example 1:
|
||||
///
|
||||
/// *mut Vec<i32>
|
||||
///
|
||||
/// Here, the "ambient" variance starts as covariant. `*mut T` is
|
||||
/// invariant with respect to `T`, so the variance in which the
|
||||
/// `Vec<i32>` appears is `Covariant.xform(Invariant)`, which
|
||||
/// yields `Invariant`. Now, the type `Vec<T>` is covariant with
|
||||
/// respect to its type argument `T`, and hence the variance of
|
||||
/// the `i32` here is `Invariant.xform(Covariant)`, which results
|
||||
/// (again) in `Invariant`.
|
||||
///
|
||||
/// Example 2:
|
||||
///
|
||||
/// fn(*const Vec<i32>, *mut Vec<i32)
|
||||
///
|
||||
/// The ambient variance is covariant. A `fn` type is
|
||||
/// contravariant with respect to its parameters, so the variance
|
||||
/// within which both pointer types appear is
|
||||
/// `Covariant.xform(Contravariant)`, or `Contravariant`. `*const
|
||||
/// T` is covariant with respect to `T`, so the variance within
|
||||
/// which the first `Vec<i32>` appears is
|
||||
/// `Contravariant.xform(Covariant)` or `Contravariant`. The same
|
||||
/// is true for its `i32` argument. In the `*mut T` case, the
|
||||
/// variance of `Vec<i32>` is `Contravariant.xform(Invariant)`,
|
||||
/// and hence the outermost type is `Invariant` with respect to
|
||||
/// `Vec<i32>` (and its `i32` argument).
|
||||
///
|
||||
/// Source: Figure 1 of "Taming the Wildcards:
|
||||
/// Combining Definition- and Use-Site Variance" published in PLDI'11.
|
||||
pub fn xform(self, v: Variance) -> Variance {
|
||||
match (self, v) {
|
||||
// Figure 1, column 1.
|
||||
(Variance::Covariant, Variance::Covariant) => Variance::Covariant,
|
||||
(Variance::Covariant, Variance::Contravariant) => Variance::Contravariant,
|
||||
(Variance::Covariant, Variance::Invariant) => Variance::Invariant,
|
||||
(Variance::Covariant, Variance::Bivariant) => Variance::Bivariant,
|
||||
|
||||
// Figure 1, column 2.
|
||||
(Variance::Contravariant, Variance::Covariant) => Variance::Contravariant,
|
||||
(Variance::Contravariant, Variance::Contravariant) => Variance::Covariant,
|
||||
(Variance::Contravariant, Variance::Invariant) => Variance::Invariant,
|
||||
(Variance::Contravariant, Variance::Bivariant) => Variance::Bivariant,
|
||||
|
||||
// Figure 1, column 3.
|
||||
(Variance::Invariant, _) => Variance::Invariant,
|
||||
|
||||
// Figure 1, column 4.
|
||||
(Variance::Bivariant, _) => Variance::Bivariant,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<CTX> HashStable<CTX> for DebruijnIndex {
|
||||
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
||||
self.as_u32().hash_stable(ctx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl<CTX> HashStable<CTX> for IntTy {
|
||||
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
||||
discriminant(self).hash_stable(ctx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl<CTX> HashStable<CTX> for UintTy {
|
||||
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
||||
discriminant(self).hash_stable(ctx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl<CTX> HashStable<CTX> for FloatTy {
|
||||
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
||||
discriminant(self).hash_stable(ctx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl<CTX> HashStable<CTX> for InferTy {
|
||||
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
||||
use InferTy::*;
|
||||
match self {
|
||||
TyVar(v) => v.index.hash_stable(ctx, hasher),
|
||||
IntVar(v) => v.index.hash_stable(ctx, hasher),
|
||||
FloatVar(v) => v.index.hash_stable(ctx, hasher),
|
||||
FreshTy(v) | FreshIntTy(v) | FreshFloatTy(v) => v.hash_stable(ctx, hasher),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<CTX> HashStable<CTX> for Variance {
|
||||
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
||||
discriminant(self).hash_stable(ctx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for IntVarValue {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
IntVarValue::IntType(ref v) => v.fmt(f),
|
||||
IntVarValue::UintType(ref v) => v.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for FloatVarValue {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for TyVid {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "_#{}t", self.index)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for IntVid {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "_#{}i", self.index)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for FloatVid {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "_#{}f", self.index)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for InferTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use InferTy::*;
|
||||
match *self {
|
||||
TyVar(ref v) => v.fmt(f),
|
||||
IntVar(ref v) => v.fmt(f),
|
||||
FloatVar(ref v) => v.fmt(f),
|
||||
FreshTy(v) => write!(f, "FreshTy({:?})", v),
|
||||
FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
|
||||
FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Variance {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(match *self {
|
||||
Variance::Covariant => "+",
|
||||
Variance::Contravariant => "-",
|
||||
Variance::Invariant => "o",
|
||||
Variance::Bivariant => "*",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for InferTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use InferTy::*;
|
||||
match *self {
|
||||
TyVar(_) => write!(f, "_"),
|
||||
IntVar(_) => write!(f, "{}", "{integer}"),
|
||||
FloatVar(_) => write!(f, "{}", "{float}"),
|
||||
FreshTy(v) => write!(f, "FreshTy({})", v),
|
||||
FreshIntTy(v) => write!(f, "FreshIntTy({})", v),
|
||||
FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2059,9 +2059,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
match prim_ty {
|
||||
hir::PrimTy::Bool => tcx.types.bool,
|
||||
hir::PrimTy::Char => tcx.types.char,
|
||||
hir::PrimTy::Int(it) => tcx.mk_mach_int(it),
|
||||
hir::PrimTy::Uint(uit) => tcx.mk_mach_uint(uit),
|
||||
hir::PrimTy::Float(ft) => tcx.mk_mach_float(ft),
|
||||
hir::PrimTy::Int(it) => tcx.mk_mach_int(ty::int_ty(it)),
|
||||
hir::PrimTy::Uint(uit) => tcx.mk_mach_uint(ty::uint_ty(uit)),
|
||||
hir::PrimTy::Float(ft) => tcx.mk_mach_float(ty::float_ty(ft)),
|
||||
hir::PrimTy::Str => tcx.types.str_,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ use super::FnCtxt;
|
|||
|
||||
use crate::hir::def_id::DefId;
|
||||
use crate::type_error_struct;
|
||||
use rustc_ast as ast;
|
||||
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
|
@ -660,7 +659,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
(_, Int(Bool)) => Err(CastError::CastToBool),
|
||||
|
||||
// * -> Char
|
||||
(Int(U(ast::UintTy::U8)), Int(Char)) => Ok(CastKind::U8CharCast), // u8-char-cast
|
||||
(Int(U(ty::UintTy::U8)), Int(Char)) => Ok(CastKind::U8CharCast), // u8-char-cast
|
||||
(_, Int(Char)) => Err(CastError::CastToChar),
|
||||
|
||||
// prim -> float,ptr
|
||||
|
|
|
@ -372,13 +372,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// in C but we just error out instead and require explicit casts.
|
||||
let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
|
||||
match arg_ty.kind() {
|
||||
ty::Float(ast::FloatTy::F32) => {
|
||||
ty::Float(ty::FloatTy::F32) => {
|
||||
variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
|
||||
}
|
||||
ty::Int(ast::IntTy::I8 | ast::IntTy::I16) | ty::Bool => {
|
||||
ty::Int(ty::IntTy::I8 | ty::IntTy::I16) | ty::Bool => {
|
||||
variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
|
||||
}
|
||||
ty::Uint(ast::UintTy::U8 | ast::UintTy::U16) => {
|
||||
ty::Uint(ty::UintTy::U8 | ty::UintTy::U16) => {
|
||||
variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
|
||||
}
|
||||
ty::FnDef(..) => {
|
||||
|
@ -407,8 +407,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
ast::LitKind::Byte(_) => tcx.types.u8,
|
||||
ast::LitKind::Char(_) => tcx.types.char,
|
||||
ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
|
||||
ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
|
||||
ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(ty::int_ty(t)),
|
||||
ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(ty::uint_ty(t)),
|
||||
ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
|
||||
let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind() {
|
||||
ty::Int(_) | ty::Uint(_) => Some(ty),
|
||||
|
@ -419,7 +419,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
});
|
||||
opt_ty.unwrap_or_else(|| self.next_int_var())
|
||||
}
|
||||
ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
|
||||
ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => {
|
||||
tcx.mk_mach_float(ty::float_ty(t))
|
||||
}
|
||||
ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
|
||||
let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind() {
|
||||
ty::Float(_) => Some(ty),
|
||||
|
|
|
@ -8,7 +8,6 @@ use crate::errors::MethodCallOnUnknownType;
|
|||
use crate::hir::def::DefKind;
|
||||
use crate::hir::def_id::DefId;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_hir as hir;
|
||||
|
@ -662,30 +661,30 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
}
|
||||
ty::Int(i) => {
|
||||
let lang_def_id = match i {
|
||||
ast::IntTy::I8 => lang_items.i8_impl(),
|
||||
ast::IntTy::I16 => lang_items.i16_impl(),
|
||||
ast::IntTy::I32 => lang_items.i32_impl(),
|
||||
ast::IntTy::I64 => lang_items.i64_impl(),
|
||||
ast::IntTy::I128 => lang_items.i128_impl(),
|
||||
ast::IntTy::Isize => lang_items.isize_impl(),
|
||||
ty::IntTy::I8 => lang_items.i8_impl(),
|
||||
ty::IntTy::I16 => lang_items.i16_impl(),
|
||||
ty::IntTy::I32 => lang_items.i32_impl(),
|
||||
ty::IntTy::I64 => lang_items.i64_impl(),
|
||||
ty::IntTy::I128 => lang_items.i128_impl(),
|
||||
ty::IntTy::Isize => lang_items.isize_impl(),
|
||||
};
|
||||
self.assemble_inherent_impl_for_primitive(lang_def_id);
|
||||
}
|
||||
ty::Uint(i) => {
|
||||
let lang_def_id = match i {
|
||||
ast::UintTy::U8 => lang_items.u8_impl(),
|
||||
ast::UintTy::U16 => lang_items.u16_impl(),
|
||||
ast::UintTy::U32 => lang_items.u32_impl(),
|
||||
ast::UintTy::U64 => lang_items.u64_impl(),
|
||||
ast::UintTy::U128 => lang_items.u128_impl(),
|
||||
ast::UintTy::Usize => lang_items.usize_impl(),
|
||||
ty::UintTy::U8 => lang_items.u8_impl(),
|
||||
ty::UintTy::U16 => lang_items.u16_impl(),
|
||||
ty::UintTy::U32 => lang_items.u32_impl(),
|
||||
ty::UintTy::U64 => lang_items.u64_impl(),
|
||||
ty::UintTy::U128 => lang_items.u128_impl(),
|
||||
ty::UintTy::Usize => lang_items.usize_impl(),
|
||||
};
|
||||
self.assemble_inherent_impl_for_primitive(lang_def_id);
|
||||
}
|
||||
ty::Float(f) => {
|
||||
let (lang_def_id1, lang_def_id2) = match f {
|
||||
ast::FloatTy::F32 => (lang_items.f32_impl(), lang_items.f32_runtime_impl()),
|
||||
ast::FloatTy::F64 => (lang_items.f64_impl(), lang_items.f64_runtime_impl()),
|
||||
ty::FloatTy::F32 => (lang_items.f32_impl(), lang_items.f32_runtime_impl()),
|
||||
ty::FloatTy::F64 => (lang_items.f64_impl(), lang_items.f64_runtime_impl()),
|
||||
};
|
||||
self.assemble_inherent_impl_for_primitive(lang_def_id1);
|
||||
self.assemble_inherent_impl_for_primitive(lang_def_id2);
|
||||
|
|
|
@ -1525,24 +1525,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
_ => return err,
|
||||
},
|
||||
[.., field] => {
|
||||
// if last field has a trailing comma, use the comma
|
||||
// as the span to avoid trailing comma in ultimate
|
||||
// suggestion (Issue #78511)
|
||||
let tail = field.span.shrink_to_hi().until(pat.span.shrink_to_hi());
|
||||
let tail_through_comma = self.tcx.sess.source_map().span_through_char(tail, ',');
|
||||
let sp = if tail_through_comma == tail {
|
||||
field.span.shrink_to_hi()
|
||||
} else {
|
||||
tail_through_comma
|
||||
};
|
||||
(
|
||||
match pat.kind {
|
||||
PatKind::Struct(_, [_, ..], _) => ", ",
|
||||
_ => "",
|
||||
},
|
||||
"",
|
||||
sp,
|
||||
)
|
||||
// Account for last field having a trailing comma or parse recovery at the tail of
|
||||
// the pattern to avoid invalid suggestion (#78511).
|
||||
let tail = field.span.shrink_to_hi().with_hi(pat.span.hi());
|
||||
match &pat.kind {
|
||||
PatKind::Struct(..) => (", ", " }", tail),
|
||||
_ => return err,
|
||||
}
|
||||
}
|
||||
};
|
||||
err.span_suggestion(
|
||||
|
|
|
@ -42,7 +42,7 @@ use rustc_infer::infer::UpvarRegion;
|
|||
use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, ProjectionKind};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, UpvarSubsts};
|
||||
use rustc_span::sym;
|
||||
use rustc_span::{Span, Symbol};
|
||||
use rustc_span::{MultiSpan, Span, Symbol};
|
||||
|
||||
/// Describe the relationship between the paths of two places
|
||||
/// eg:
|
||||
|
@ -135,7 +135,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
let upvar_id = ty::UpvarId::new(var_hir_id, local_def_id);
|
||||
let capture_kind = self.init_capture_kind(capture_clause, upvar_id, span);
|
||||
let info = ty::CaptureInfo { expr_id: None, capture_kind };
|
||||
let info = ty::CaptureInfo {
|
||||
capture_kind_expr_id: None,
|
||||
path_expr_id: None,
|
||||
capture_kind,
|
||||
};
|
||||
|
||||
capture_information.insert(place, info);
|
||||
}
|
||||
|
@ -308,8 +312,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
if let Some(capture_kind) = upvar_capture_map.get(&upvar_id) {
|
||||
// upvar_capture_map only stores the UpvarCapture (CaptureKind),
|
||||
// so we create a fake capture info with no expression.
|
||||
let fake_capture_info =
|
||||
ty::CaptureInfo { expr_id: None, capture_kind: *capture_kind };
|
||||
let fake_capture_info = ty::CaptureInfo {
|
||||
capture_kind_expr_id: None,
|
||||
path_expr_id: None,
|
||||
capture_kind: *capture_kind,
|
||||
};
|
||||
determine_capture_info(fake_capture_info, capture_info).capture_kind
|
||||
} else {
|
||||
capture_info.capture_kind
|
||||
|
@ -359,20 +366,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
///
|
||||
/// ```
|
||||
/// {
|
||||
/// Place(base: hir_id_s, projections: [], ....) -> (hir_id_L5, ByValue),
|
||||
/// Place(base: hir_id_p, projections: [Field(0, 0)], ...) -> (hir_id_L2, ByRef(MutBorrow))
|
||||
/// Place(base: hir_id_p, projections: [Field(1, 0)], ...) -> (hir_id_L3, ByRef(ImmutBorrow))
|
||||
/// Place(base: hir_id_p, projections: [], ...) -> (hir_id_L4, ByRef(ImmutBorrow))
|
||||
/// Place(base: hir_id_s, projections: [], ....) -> {
|
||||
/// capture_kind_expr: hir_id_L5,
|
||||
/// path_expr_id: hir_id_L5,
|
||||
/// capture_kind: ByValue
|
||||
/// },
|
||||
/// Place(base: hir_id_p, projections: [Field(0, 0)], ...) -> {
|
||||
/// capture_kind_expr: hir_id_L2,
|
||||
/// path_expr_id: hir_id_L2,
|
||||
/// capture_kind: ByValue
|
||||
/// },
|
||||
/// Place(base: hir_id_p, projections: [Field(1, 0)], ...) -> {
|
||||
/// capture_kind_expr: hir_id_L3,
|
||||
/// path_expr_id: hir_id_L3,
|
||||
/// capture_kind: ByValue
|
||||
/// },
|
||||
/// Place(base: hir_id_p, projections: [], ...) -> {
|
||||
/// capture_kind_expr: hir_id_L4,
|
||||
/// path_expr_id: hir_id_L4,
|
||||
/// capture_kind: ByValue
|
||||
/// },
|
||||
/// ```
|
||||
///
|
||||
/// After the min capture analysis, we get:
|
||||
/// ```
|
||||
/// {
|
||||
/// hir_id_s -> [
|
||||
/// Place(base: hir_id_s, projections: [], ....) -> (hir_id_L4, ByValue)
|
||||
/// Place(base: hir_id_s, projections: [], ....) -> {
|
||||
/// capture_kind_expr: hir_id_L5,
|
||||
/// path_expr_id: hir_id_L5,
|
||||
/// capture_kind: ByValue
|
||||
/// },
|
||||
/// ],
|
||||
/// hir_id_p -> [
|
||||
/// Place(base: hir_id_p, projections: [], ...) -> (hir_id_L2, ByRef(MutBorrow)),
|
||||
/// Place(base: hir_id_p, projections: [], ...) -> {
|
||||
/// capture_kind_expr: hir_id_L2,
|
||||
/// path_expr_id: hir_id_L4,
|
||||
/// capture_kind: ByValue
|
||||
/// },
|
||||
/// ],
|
||||
/// ```
|
||||
fn compute_min_captures(
|
||||
|
@ -425,8 +456,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// current place is ancestor of possible_descendant
|
||||
PlaceAncestryRelation::Ancestor => {
|
||||
descendant_found = true;
|
||||
let backup_path_expr_id = updated_capture_info.path_expr_id;
|
||||
|
||||
updated_capture_info =
|
||||
determine_capture_info(updated_capture_info, possible_descendant.info);
|
||||
|
||||
// we need to keep the ancestor's `path_expr_id`
|
||||
updated_capture_info.path_expr_id = backup_path_expr_id;
|
||||
false
|
||||
}
|
||||
|
||||
|
@ -441,9 +477,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// current place is descendant of possible_ancestor
|
||||
PlaceAncestryRelation::Descendant => {
|
||||
ancestor_found = true;
|
||||
let backup_path_expr_id = possible_ancestor.info.path_expr_id;
|
||||
possible_ancestor.info =
|
||||
determine_capture_info(possible_ancestor.info, capture_info);
|
||||
|
||||
// we need to keep the ancestor's `path_expr_id`
|
||||
possible_ancestor.info.path_expr_id = backup_path_expr_id;
|
||||
|
||||
// Only one ancestor of the current place will be in the list.
|
||||
break;
|
||||
}
|
||||
|
@ -518,7 +558,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let capture_str = construct_capture_info_string(self.tcx, place, capture_info);
|
||||
let output_str = format!("Capturing {}", capture_str);
|
||||
|
||||
let span = capture_info.expr_id.map_or(closure_span, |e| self.tcx.hir().span(e));
|
||||
let span =
|
||||
capture_info.path_expr_id.map_or(closure_span, |e| self.tcx.hir().span(e));
|
||||
diag.span_note(span, &output_str);
|
||||
}
|
||||
diag.emit();
|
||||
|
@ -542,9 +583,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
construct_capture_info_string(self.tcx, place, capture_info);
|
||||
let output_str = format!("Min Capture {}", capture_str);
|
||||
|
||||
let span =
|
||||
capture_info.expr_id.map_or(closure_span, |e| self.tcx.hir().span(e));
|
||||
diag.span_note(span, &output_str);
|
||||
if capture.info.path_expr_id != capture.info.capture_kind_expr_id {
|
||||
let path_span = capture_info
|
||||
.path_expr_id
|
||||
.map_or(closure_span, |e| self.tcx.hir().span(e));
|
||||
let capture_kind_span = capture_info
|
||||
.capture_kind_expr_id
|
||||
.map_or(closure_span, |e| self.tcx.hir().span(e));
|
||||
|
||||
let mut multi_span: MultiSpan =
|
||||
MultiSpan::from_spans(vec![path_span, capture_kind_span]);
|
||||
|
||||
let capture_kind_label =
|
||||
construct_capture_kind_reason_string(self.tcx, place, capture_info);
|
||||
let path_label = construct_path_string(self.tcx, place);
|
||||
|
||||
multi_span.push_span_label(path_span, path_label);
|
||||
multi_span.push_span_label(capture_kind_span, capture_kind_label);
|
||||
|
||||
diag.span_note(multi_span, &output_str);
|
||||
} else {
|
||||
let span = capture_info
|
||||
.path_expr_id
|
||||
.map_or(closure_span, |e| self.tcx.hir().span(e));
|
||||
|
||||
diag.span_note(span, &output_str);
|
||||
};
|
||||
}
|
||||
}
|
||||
diag.emit();
|
||||
|
@ -642,7 +706,8 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
|
|||
);
|
||||
|
||||
let capture_info = ty::CaptureInfo {
|
||||
expr_id: Some(diag_expr_id),
|
||||
capture_kind_expr_id: Some(diag_expr_id),
|
||||
path_expr_id: Some(diag_expr_id),
|
||||
capture_kind: ty::UpvarCapture::ByValue(Some(usage_span)),
|
||||
};
|
||||
|
||||
|
@ -762,7 +827,8 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
|
|||
let new_upvar_borrow = ty::UpvarBorrow { kind, region: curr_upvar_borrow.region };
|
||||
|
||||
let capture_info = ty::CaptureInfo {
|
||||
expr_id: Some(diag_expr_id),
|
||||
capture_kind_expr_id: Some(diag_expr_id),
|
||||
path_expr_id: Some(diag_expr_id),
|
||||
capture_kind: ty::UpvarCapture::ByRef(new_upvar_borrow),
|
||||
};
|
||||
let updated_info = determine_capture_info(curr_capture_info, capture_info);
|
||||
|
@ -824,7 +890,11 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
|
|||
self.fcx.init_capture_kind(self.capture_clause, upvar_id, self.closure_span);
|
||||
|
||||
let expr_id = Some(diag_expr_id);
|
||||
let capture_info = ty::CaptureInfo { expr_id, capture_kind };
|
||||
let capture_info = ty::CaptureInfo {
|
||||
capture_kind_expr_id: expr_id,
|
||||
path_expr_id: expr_id,
|
||||
capture_kind,
|
||||
};
|
||||
|
||||
debug!("Capturing new place {:?}, capture_info={:?}", place_with_id, capture_info);
|
||||
|
||||
|
@ -890,11 +960,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn construct_capture_info_string(
|
||||
tcx: TyCtxt<'_>,
|
||||
place: &Place<'tcx>,
|
||||
capture_info: &ty::CaptureInfo<'tcx>,
|
||||
) -> String {
|
||||
fn construct_place_string(tcx: TyCtxt<'_>, place: &Place<'tcx>) -> String {
|
||||
let variable_name = match place.base {
|
||||
PlaceBase::Upvar(upvar_id) => var_name(tcx, upvar_id.var_path.hir_id).to_string(),
|
||||
_ => bug!("Capture_information should only contain upvars"),
|
||||
|
@ -914,11 +980,42 @@ fn construct_capture_info_string(
|
|||
projections_str.push_str(proj.as_str());
|
||||
}
|
||||
|
||||
format!("{}[{}]", variable_name, projections_str)
|
||||
}
|
||||
|
||||
fn construct_capture_kind_reason_string(
|
||||
tcx: TyCtxt<'_>,
|
||||
place: &Place<'tcx>,
|
||||
capture_info: &ty::CaptureInfo<'tcx>,
|
||||
) -> String {
|
||||
let place_str = construct_place_string(tcx, &place);
|
||||
|
||||
let capture_kind_str = match capture_info.capture_kind {
|
||||
ty::UpvarCapture::ByValue(_) => "ByValue".into(),
|
||||
ty::UpvarCapture::ByRef(borrow) => format!("{:?}", borrow.kind),
|
||||
};
|
||||
format!("{}[{}] -> {}", variable_name, projections_str, capture_kind_str)
|
||||
|
||||
format!("{} captured as {} here", place_str, capture_kind_str)
|
||||
}
|
||||
|
||||
fn construct_path_string(tcx: TyCtxt<'_>, place: &Place<'tcx>) -> String {
|
||||
let place_str = construct_place_string(tcx, &place);
|
||||
|
||||
format!("{} used here", place_str)
|
||||
}
|
||||
|
||||
fn construct_capture_info_string(
|
||||
tcx: TyCtxt<'_>,
|
||||
place: &Place<'tcx>,
|
||||
capture_info: &ty::CaptureInfo<'tcx>,
|
||||
) -> String {
|
||||
let place_str = construct_place_string(tcx, &place);
|
||||
|
||||
let capture_kind_str = match capture_info.capture_kind {
|
||||
ty::UpvarCapture::ByValue(_) => "ByValue".into(),
|
||||
ty::UpvarCapture::ByRef(borrow) => format!("{:?}", borrow.kind),
|
||||
};
|
||||
format!("{} -> {}", place_str, capture_kind_str)
|
||||
}
|
||||
|
||||
fn var_name(tcx: TyCtxt<'_>, var_hir_id: hir::HirId) -> Symbol {
|
||||
|
@ -930,7 +1027,9 @@ fn var_name(tcx: TyCtxt<'_>, var_hir_id: hir::HirId) -> Symbol {
|
|||
/// (Note: CaptureInfo contains CaptureKind and an expression that led to capture it in that way)
|
||||
///
|
||||
/// If both `CaptureKind`s are considered equivalent, then the CaptureInfo is selected based
|
||||
/// on the `CaptureInfo` containing an associated expression id.
|
||||
/// on the `CaptureInfo` containing an associated `capture_kind_expr_id`.
|
||||
///
|
||||
/// It is the caller's duty to figure out which path_expr_id to use.
|
||||
///
|
||||
/// If both the CaptureKind and Expression are considered to be equivalent,
|
||||
/// then `CaptureInfo` A is preferred. This can be useful in cases where we want to priortize
|
||||
|
@ -981,7 +1080,7 @@ fn determine_capture_info(
|
|||
};
|
||||
|
||||
if eq_capture_kind {
|
||||
match (capture_info_a.expr_id, capture_info_b.expr_id) {
|
||||
match (capture_info_a.capture_kind_expr_id, capture_info_b.capture_kind_expr_id) {
|
||||
(Some(_), _) | (None, None) => capture_info_a,
|
||||
(None, Some(_)) => capture_info_b,
|
||||
}
|
||||
|
|
|
@ -348,7 +348,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
let min_list_wb = min_list
|
||||
.iter()
|
||||
.map(|captured_place| {
|
||||
let locatable = captured_place.info.expr_id.unwrap_or(
|
||||
let locatable = captured_place.info.path_expr_id.unwrap_or(
|
||||
self.tcx().hir().local_def_id_to_hir_id(closure_def_id.expect_local()),
|
||||
);
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
|
|||
use rustc_hir::itemlikevisit::ItemLikeVisitor;
|
||||
use rustc_middle::ty::{self, CrateInherentImpls, TyCtxt};
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_span::Span;
|
||||
|
||||
/// On-demand query: yields a map containing all types mapped to their inherent impls.
|
||||
|
@ -178,7 +177,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
|
|||
assoc_items,
|
||||
);
|
||||
}
|
||||
ty::Int(ast::IntTy::I8) => {
|
||||
ty::Int(ty::IntTy::I8) => {
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
lang_items.i8_impl(),
|
||||
|
@ -189,7 +188,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
|
|||
assoc_items,
|
||||
);
|
||||
}
|
||||
ty::Int(ast::IntTy::I16) => {
|
||||
ty::Int(ty::IntTy::I16) => {
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
lang_items.i16_impl(),
|
||||
|
@ -200,7 +199,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
|
|||
assoc_items,
|
||||
);
|
||||
}
|
||||
ty::Int(ast::IntTy::I32) => {
|
||||
ty::Int(ty::IntTy::I32) => {
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
lang_items.i32_impl(),
|
||||
|
@ -211,7 +210,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
|
|||
assoc_items,
|
||||
);
|
||||
}
|
||||
ty::Int(ast::IntTy::I64) => {
|
||||
ty::Int(ty::IntTy::I64) => {
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
lang_items.i64_impl(),
|
||||
|
@ -222,7 +221,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
|
|||
assoc_items,
|
||||
);
|
||||
}
|
||||
ty::Int(ast::IntTy::I128) => {
|
||||
ty::Int(ty::IntTy::I128) => {
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
lang_items.i128_impl(),
|
||||
|
@ -233,7 +232,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
|
|||
assoc_items,
|
||||
);
|
||||
}
|
||||
ty::Int(ast::IntTy::Isize) => {
|
||||
ty::Int(ty::IntTy::Isize) => {
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
lang_items.isize_impl(),
|
||||
|
@ -244,7 +243,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
|
|||
assoc_items,
|
||||
);
|
||||
}
|
||||
ty::Uint(ast::UintTy::U8) => {
|
||||
ty::Uint(ty::UintTy::U8) => {
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
lang_items.u8_impl(),
|
||||
|
@ -255,7 +254,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
|
|||
assoc_items,
|
||||
);
|
||||
}
|
||||
ty::Uint(ast::UintTy::U16) => {
|
||||
ty::Uint(ty::UintTy::U16) => {
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
lang_items.u16_impl(),
|
||||
|
@ -266,7 +265,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
|
|||
assoc_items,
|
||||
);
|
||||
}
|
||||
ty::Uint(ast::UintTy::U32) => {
|
||||
ty::Uint(ty::UintTy::U32) => {
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
lang_items.u32_impl(),
|
||||
|
@ -277,7 +276,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
|
|||
assoc_items,
|
||||
);
|
||||
}
|
||||
ty::Uint(ast::UintTy::U64) => {
|
||||
ty::Uint(ty::UintTy::U64) => {
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
lang_items.u64_impl(),
|
||||
|
@ -288,7 +287,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
|
|||
assoc_items,
|
||||
);
|
||||
}
|
||||
ty::Uint(ast::UintTy::U128) => {
|
||||
ty::Uint(ty::UintTy::U128) => {
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
lang_items.u128_impl(),
|
||||
|
@ -299,7 +298,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
|
|||
assoc_items,
|
||||
);
|
||||
}
|
||||
ty::Uint(ast::UintTy::Usize) => {
|
||||
ty::Uint(ty::UintTy::Usize) => {
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
lang_items.usize_impl(),
|
||||
|
@ -310,7 +309,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
|
|||
assoc_items,
|
||||
);
|
||||
}
|
||||
ty::Float(ast::FloatTy::F32) => {
|
||||
ty::Float(ty::FloatTy::F32) => {
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
lang_items.f32_impl(),
|
||||
|
@ -321,7 +320,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
|
|||
assoc_items,
|
||||
);
|
||||
}
|
||||
ty::Float(ast::FloatTy::F64) => {
|
||||
ty::Float(ty::FloatTy::F64) => {
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
lang_items.f64_impl(),
|
||||
|
|
|
@ -50,8 +50,6 @@ use rustc_span::{Span, DUMMY_SP};
|
|||
use rustc_target::spec::abi;
|
||||
use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
|
||||
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
mod item_bounds;
|
||||
mod type_of;
|
||||
|
||||
|
@ -2080,38 +2078,6 @@ fn const_evaluatable_predicates_of<'tcx>(
|
|||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Look into `TyAlias`.
|
||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
||||
use ty::fold::{TypeFoldable, TypeVisitor};
|
||||
struct TyAliasVisitor<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
preds: &'a mut FxIndexSet<(ty::Predicate<'tcx>, Span)>,
|
||||
span: Span,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeVisitor<'tcx> for TyAliasVisitor<'a, 'tcx> {
|
||||
fn visit_const(&mut self, ct: &'tcx Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
if let ty::ConstKind::Unevaluated(def, substs, None) = ct.val {
|
||||
self.preds.insert((
|
||||
ty::PredicateKind::ConstEvaluatable(def, substs).to_predicate(self.tcx),
|
||||
self.span,
|
||||
));
|
||||
}
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
|
||||
if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind {
|
||||
if let Res::Def(DefKind::TyAlias, def_id) = path.res {
|
||||
let mut visitor =
|
||||
TyAliasVisitor { tcx: self.tcx, preds: &mut self.preds, span: path.span };
|
||||
self.tcx.type_of(def_id).visit_with(&mut visitor);
|
||||
}
|
||||
}
|
||||
|
||||
intravisit::walk_ty(self, ty)
|
||||
}
|
||||
}
|
||||
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
|
|
|
@ -630,7 +630,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
|||
PlaceBase::Local(*var_hir_id)
|
||||
};
|
||||
let place_with_id = PlaceWithHirId::new(
|
||||
capture_info.expr_id.unwrap_or(closure_expr.hir_id),
|
||||
capture_info.path_expr_id.unwrap_or(closure_expr.hir_id),
|
||||
place.base_ty,
|
||||
place_base,
|
||||
place.projections.clone(),
|
||||
|
|
|
@ -267,6 +267,7 @@ pub trait AsMut<T: ?Sized> {
|
|||
///
|
||||
/// [`String`]: ../../std/string/struct.String.html
|
||||
/// [`Vec`]: ../../std/vec/struct.Vec.html
|
||||
#[rustc_diagnostic_item = "into_trait"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Into<T>: Sized {
|
||||
/// Performs the conversion.
|
||||
|
@ -382,6 +383,7 @@ pub trait From<T>: Sized {
|
|||
///
|
||||
/// This suffers the same restrictions and reasoning as implementing
|
||||
/// [`Into`], see there for details.
|
||||
#[rustc_diagnostic_item = "try_into_trait"]
|
||||
#[stable(feature = "try_from", since = "1.34.0")]
|
||||
pub trait TryInto<T>: Sized {
|
||||
/// The type returned in the event of a conversion error.
|
||||
|
@ -462,6 +464,7 @@ pub trait TryInto<T>: Sized {
|
|||
///
|
||||
/// [`try_from`]: TryFrom::try_from
|
||||
/// [`!`]: ../../std/primitive.never.html
|
||||
#[rustc_diagnostic_item = "try_from_trait"]
|
||||
#[stable(feature = "try_from", since = "1.34.0")]
|
||||
pub trait TryFrom<T>: Sized {
|
||||
/// The type returned in the event of a conversion error.
|
||||
|
|
|
@ -410,7 +410,6 @@ impl<R: Seek> Seek for BufReader<R> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(seek_convenience)]
|
||||
/// use std::{
|
||||
/// io::{self, BufRead, BufReader, Seek},
|
||||
/// fs::File,
|
||||
|
|
|
@ -1671,7 +1671,7 @@ pub trait Seek {
|
|||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(seek_convenience)]
|
||||
/// #![feature(seek_stream_len)]
|
||||
/// use std::{
|
||||
/// io::{self, Seek},
|
||||
/// fs::File,
|
||||
|
@ -1685,7 +1685,7 @@ pub trait Seek {
|
|||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "seek_convenience", issue = "59359")]
|
||||
#[unstable(feature = "seek_stream_len", issue = "59359")]
|
||||
fn stream_len(&mut self) -> Result<u64> {
|
||||
let old_pos = self.stream_position()?;
|
||||
let len = self.seek(SeekFrom::End(0))?;
|
||||
|
@ -1706,7 +1706,6 @@ pub trait Seek {
|
|||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(seek_convenience)]
|
||||
/// use std::{
|
||||
/// io::{self, BufRead, BufReader, Seek},
|
||||
/// fs::File,
|
||||
|
@ -1723,7 +1722,7 @@ pub trait Seek {
|
|||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "seek_convenience", issue = "59359")]
|
||||
#[stable(feature = "seek_convenience", since = "1.51.0")]
|
||||
fn stream_position(&mut self) -> Result<u64> {
|
||||
self.seek(SeekFrom::Current(0))
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ pub fn calc_result<'a>(
|
|||
))
|
||||
}
|
||||
}
|
||||
(&ShouldPanic::Yes, Ok(())) => {
|
||||
(&ShouldPanic::Yes, Ok(())) | (&ShouldPanic::YesWithMessage(_), Ok(())) => {
|
||||
TestResult::TrFailedMsg("test did not panic as expected".to_string())
|
||||
}
|
||||
_ if desc.allow_fail => TestResult::TrAllowedFail,
|
||||
|
|
|
@ -228,21 +228,30 @@ fn test_should_panic_non_string_message_type() {
|
|||
#[test]
|
||||
#[cfg(not(target_os = "emscripten"))]
|
||||
fn test_should_panic_but_succeeds() {
|
||||
fn f() {}
|
||||
let desc = TestDescAndFn {
|
||||
desc: TestDesc {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
should_panic: ShouldPanic::Yes,
|
||||
allow_fail: false,
|
||||
test_type: TestType::Unknown,
|
||||
},
|
||||
testfn: DynTestFn(Box::new(f)),
|
||||
};
|
||||
let (tx, rx) = channel();
|
||||
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
|
||||
let result = rx.recv().unwrap().result;
|
||||
assert_eq!(result, TrFailedMsg("test did not panic as expected".to_string()));
|
||||
let should_panic_variants = [ShouldPanic::Yes, ShouldPanic::YesWithMessage("error message")];
|
||||
|
||||
for &should_panic in should_panic_variants.iter() {
|
||||
fn f() {}
|
||||
let desc = TestDescAndFn {
|
||||
desc: TestDesc {
|
||||
name: StaticTestName("whatever"),
|
||||
ignore: false,
|
||||
should_panic,
|
||||
allow_fail: false,
|
||||
test_type: TestType::Unknown,
|
||||
},
|
||||
testfn: DynTestFn(Box::new(f)),
|
||||
};
|
||||
let (tx, rx) = channel();
|
||||
run_test(&TestOpts::new(), false, desc, RunStrategy::InProcess, tx, Concurrent::No);
|
||||
let result = rx.recv().unwrap().result;
|
||||
assert_eq!(
|
||||
result,
|
||||
TrFailedMsg("test did not panic as expected".to_string()),
|
||||
"should_panic == {:?}",
|
||||
should_panic
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn report_time_test_template(report_time: bool) -> Option<TestExecTime> {
|
||||
|
|
|
@ -11,7 +11,6 @@ use std::{slice, vec};
|
|||
use rustc_ast::attr;
|
||||
use rustc_ast::util::comments::beautify_doc_string;
|
||||
use rustc_ast::{self as ast, AttrStyle};
|
||||
use rustc_ast::{FloatTy, IntTy, UintTy};
|
||||
use rustc_attr::{ConstStability, Deprecation, Stability, StabilityLevel};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_feature::UnstableFeatures;
|
||||
|
@ -21,7 +20,7 @@ use rustc_hir::def_id::{CrateNum, DefId};
|
|||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::Mutability;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::source_map::DUMMY_SP;
|
||||
|
@ -1456,6 +1455,7 @@ impl GetDefId for Type {
|
|||
|
||||
impl PrimitiveType {
|
||||
crate fn from_hir(prim: hir::PrimTy) -> PrimitiveType {
|
||||
use ast::{FloatTy, IntTy, UintTy};
|
||||
match prim {
|
||||
hir::PrimTy::Int(IntTy::Isize) => PrimitiveType::Isize,
|
||||
hir::PrimTy::Int(IntTy::I8) => PrimitiveType::I8,
|
||||
|
@ -1690,6 +1690,41 @@ impl From<ast::FloatTy> for PrimitiveType {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<ty::IntTy> for PrimitiveType {
|
||||
fn from(int_ty: ty::IntTy) -> PrimitiveType {
|
||||
match int_ty {
|
||||
ty::IntTy::Isize => PrimitiveType::Isize,
|
||||
ty::IntTy::I8 => PrimitiveType::I8,
|
||||
ty::IntTy::I16 => PrimitiveType::I16,
|
||||
ty::IntTy::I32 => PrimitiveType::I32,
|
||||
ty::IntTy::I64 => PrimitiveType::I64,
|
||||
ty::IntTy::I128 => PrimitiveType::I128,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ty::UintTy> for PrimitiveType {
|
||||
fn from(uint_ty: ty::UintTy) -> PrimitiveType {
|
||||
match uint_ty {
|
||||
ty::UintTy::Usize => PrimitiveType::Usize,
|
||||
ty::UintTy::U8 => PrimitiveType::U8,
|
||||
ty::UintTy::U16 => PrimitiveType::U16,
|
||||
ty::UintTy::U32 => PrimitiveType::U32,
|
||||
ty::UintTy::U64 => PrimitiveType::U64,
|
||||
ty::UintTy::U128 => PrimitiveType::U128,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ty::FloatTy> for PrimitiveType {
|
||||
fn from(float_ty: ty::FloatTy) -> PrimitiveType {
|
||||
match float_ty {
|
||||
ty::FloatTy::F32 => PrimitiveType::F32,
|
||||
ty::FloatTy::F64 => PrimitiveType::F64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<hir::PrimTy> for PrimitiveType {
|
||||
fn from(prim_ty: hir::PrimTy) -> PrimitiveType {
|
||||
match prim_ty {
|
||||
|
|
|
@ -487,12 +487,16 @@ crate fn get_auto_trait_and_blanket_impls(
|
|||
ty: Ty<'tcx>,
|
||||
param_env_def_id: DefId,
|
||||
) -> impl Iterator<Item = Item> {
|
||||
let auto_impls = cx.sess().time("get_auto_trait_impls", || {
|
||||
AutoTraitFinder::new(cx).get_auto_trait_impls(ty, param_env_def_id)
|
||||
});
|
||||
let blanket_impls = cx.sess().time("get_blanket_impls", || {
|
||||
BlanketImplFinder::new(cx).get_blanket_impls(ty, param_env_def_id)
|
||||
});
|
||||
let auto_impls = cx
|
||||
.sess()
|
||||
.prof
|
||||
.generic_activity("get_auto_trait_impls")
|
||||
.run(|| AutoTraitFinder::new(cx).get_auto_trait_impls(ty, param_env_def_id));
|
||||
let blanket_impls = cx
|
||||
.sess()
|
||||
.prof
|
||||
.generic_activity("get_blanket_impls")
|
||||
.run(|| BlanketImplFinder::new(cx).get_blanket_impls(ty, param_env_def_id));
|
||||
auto_impls.into_iter().chain(blanket_impls)
|
||||
}
|
||||
|
||||
|
|
|
@ -91,6 +91,11 @@ function getThemePickerElement() {
|
|||
return document.getElementById("theme-picker");
|
||||
}
|
||||
|
||||
// Returns the current URL without any query parameter or hash.
|
||||
function getNakedUrl() {
|
||||
return window.location.href.split("?")[0].split("#")[0];
|
||||
}
|
||||
|
||||
// Sets the focus on the search bar at the top of the page
|
||||
function focusSearchBar() {
|
||||
getSearchInput().focus();
|
||||
|
@ -252,7 +257,9 @@ function defocusSearchBar() {
|
|||
hideSearchResults(search);
|
||||
var hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1);
|
||||
if (browserSupportsHistoryApi()) {
|
||||
history.replaceState(hash, "", "?search=#" + hash);
|
||||
// `window.location.search`` contains all the query parameters, not just `search`.
|
||||
history.replaceState(hash, "",
|
||||
getNakedUrl() + window.location.search + "#" + hash);
|
||||
}
|
||||
elem = document.getElementById(hash);
|
||||
if (elem) {
|
||||
|
@ -1810,10 +1817,12 @@ function defocusSearchBar() {
|
|||
// Because searching is incremental by character, only the most
|
||||
// recent search query is added to the browser history.
|
||||
if (browserSupportsHistoryApi()) {
|
||||
var newURL = getNakedUrl() + "?search=" + encodeURIComponent(query.raw) +
|
||||
window.location.hash;
|
||||
if (!history.state && !params.search) {
|
||||
history.pushState(query, "", "?search=" + encodeURIComponent(query.raw));
|
||||
history.pushState(query, "", newURL);
|
||||
} else {
|
||||
history.replaceState(query, "", "?search=" + encodeURIComponent(query.raw));
|
||||
history.replaceState(query, "", newURL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1922,7 +1931,8 @@ function defocusSearchBar() {
|
|||
clearInputTimeout();
|
||||
if (search_input.value.length === 0) {
|
||||
if (browserSupportsHistoryApi()) {
|
||||
history.replaceState("", window.currentCrate + " - Rust", "?search=");
|
||||
history.replaceState("", window.currentCrate + " - Rust",
|
||||
getNakedUrl() + window.location.hash);
|
||||
}
|
||||
hideSearchResults();
|
||||
} else {
|
||||
|
@ -2779,9 +2789,9 @@ function defocusSearchBar() {
|
|||
if (search_input.value !== "" && hasClass(search, "hidden")) {
|
||||
showSearchResults(search);
|
||||
if (browserSupportsHistoryApi()) {
|
||||
history.replaceState(search_input.value,
|
||||
"",
|
||||
"?search=" + encodeURIComponent(search_input.value));
|
||||
var extra = "?search=" + encodeURIComponent(search_input.value);
|
||||
history.replaceState(search_input.value, "",
|
||||
getNakedUrl() + extra + window.location.hash);
|
||||
}
|
||||
document.title = searchTitle;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
|
|||
|
||||
for &cnum in cx.tcx.crates().iter() {
|
||||
for &(did, _) in cx.tcx.all_trait_implementations(cnum).iter() {
|
||||
cx.tcx.sess.time("build_extern_trait_impl", || {
|
||||
cx.tcx.sess.prof.generic_activity("build_extern_trait_impl").run(|| {
|
||||
inline::build_impl(cx, None, did, None, &mut new_items);
|
||||
});
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
|
|||
// Also try to inline primitive impls from other crates.
|
||||
for &def_id in PrimitiveType::all_impls(cx.tcx).values().flatten() {
|
||||
if !def_id.is_local() {
|
||||
cx.sess().time("build_primitive_trait_impl", || {
|
||||
cx.tcx.sess.prof.generic_activity("build_primitive_trait_impls").run(|| {
|
||||
inline::build_impl(cx, None, def_id, None, &mut new_items);
|
||||
|
||||
// FIXME(eddyb) is this `doc(hidden)` check needed?
|
||||
|
@ -59,7 +59,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
|
|||
for &trait_did in cx.tcx.all_traits(LOCAL_CRATE).iter() {
|
||||
for &impl_node in cx.tcx.hir().trait_impls(trait_did) {
|
||||
let impl_did = cx.tcx.hir().local_def_id(impl_node);
|
||||
cx.tcx.sess.time("build_local_trait_impl", || {
|
||||
cx.tcx.sess.prof.generic_activity("build_local_trait_impl").run(|| {
|
||||
let mut extra_attrs = Vec::new();
|
||||
let mut parent = cx.tcx.parent(impl_did.to_def_id());
|
||||
while let Some(did) = parent {
|
||||
|
@ -177,13 +177,11 @@ impl<'a, 'tcx> DocFolder for SyntheticImplCollector<'a, 'tcx> {
|
|||
if i.is_struct() || i.is_enum() || i.is_union() {
|
||||
// FIXME(eddyb) is this `doc(hidden)` check needed?
|
||||
if !self.cx.tcx.get_attrs(i.def_id).lists(sym::doc).has_word(sym::hidden) {
|
||||
self.cx.sess().time("get_auto_trait_and_blanket_synthetic_impls", || {
|
||||
self.impls.extend(get_auto_trait_and_blanket_impls(
|
||||
self.cx,
|
||||
self.cx.tcx.type_of(i.def_id),
|
||||
i.def_id,
|
||||
));
|
||||
});
|
||||
self.impls.extend(get_auto_trait_and_blanket_impls(
|
||||
self.cx,
|
||||
self.cx.tcx.type_of(i.def_id),
|
||||
i.def_id,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
//~| NOTE: `#[warn(incomplete_features)]` on by default
|
||||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let p = Point { x: 10, y: 10 };
|
||||
let q = Point { x: 10, y: 10 };
|
||||
|
||||
let c = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
||||
|| {
|
||||
//~^ First Pass analysis includes:
|
||||
//~| Min Capture analysis includes:
|
||||
println!("{:?}", p);
|
||||
//~^ NOTE: Capturing p[] -> ImmBorrow
|
||||
//~| NOTE: Min Capture p[] -> ImmBorrow
|
||||
println!("{:?}", p.x);
|
||||
//~^ NOTE: Capturing p[(0, 0)] -> ImmBorrow
|
||||
|
||||
println!("{:?}", q.x);
|
||||
//~^ NOTE: Capturing q[(0, 0)] -> ImmBorrow
|
||||
println!("{:?}", q);
|
||||
//~^ NOTE: Capturing q[] -> ImmBorrow
|
||||
//~| NOTE: Min Capture q[] -> ImmBorrow
|
||||
};
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/capture-analysis-1.rs:17:13
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/capture-analysis-1.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/capture-analysis-1.rs:20:5
|
||||
|
|
||||
LL | / || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | println!("{:?}", p);
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Capturing p[] -> ImmBorrow
|
||||
--> $DIR/capture-analysis-1.rs:23:26
|
||||
|
|
||||
LL | println!("{:?}", p);
|
||||
| ^
|
||||
note: Capturing p[(0, 0)] -> ImmBorrow
|
||||
--> $DIR/capture-analysis-1.rs:26:26
|
||||
|
|
||||
LL | println!("{:?}", p.x);
|
||||
| ^^^
|
||||
note: Capturing q[(0, 0)] -> ImmBorrow
|
||||
--> $DIR/capture-analysis-1.rs:29:26
|
||||
|
|
||||
LL | println!("{:?}", q.x);
|
||||
| ^^^
|
||||
note: Capturing q[] -> ImmBorrow
|
||||
--> $DIR/capture-analysis-1.rs:31:26
|
||||
|
|
||||
LL | println!("{:?}", q);
|
||||
| ^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/capture-analysis-1.rs:20:5
|
||||
|
|
||||
LL | / || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | println!("{:?}", p);
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Min Capture p[] -> ImmBorrow
|
||||
--> $DIR/capture-analysis-1.rs:23:26
|
||||
|
|
||||
LL | println!("{:?}", p);
|
||||
| ^
|
||||
note: Min Capture q[] -> ImmBorrow
|
||||
--> $DIR/capture-analysis-1.rs:31:26
|
||||
|
|
||||
LL | println!("{:?}", q);
|
||||
| ^
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,30 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
//~| NOTE: `#[warn(incomplete_features)]` on by default
|
||||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Point {
|
||||
x: String,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut p = Point { x: String::new(), y: 10 };
|
||||
|
||||
let c = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
||||
|| {
|
||||
//~^ First Pass analysis includes:
|
||||
//~| Min Capture analysis includes:
|
||||
let _x = p.x;
|
||||
//~^ NOTE: Capturing p[(0, 0)] -> ByValue
|
||||
//~| NOTE: p[] captured as ByValue here
|
||||
println!("{:?}", p);
|
||||
//~^ NOTE: Capturing p[] -> ImmBorrow
|
||||
//~| NOTE: Min Capture p[] -> ByValue
|
||||
//~| NOTE: p[] used here
|
||||
};
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/capture-analysis-2.rs:16:13
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/capture-analysis-2.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/capture-analysis-2.rs:19:5
|
||||
|
|
||||
LL | / || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let _x = p.x;
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Capturing p[(0, 0)] -> ByValue
|
||||
--> $DIR/capture-analysis-2.rs:22:18
|
||||
|
|
||||
LL | let _x = p.x;
|
||||
| ^^^
|
||||
note: Capturing p[] -> ImmBorrow
|
||||
--> $DIR/capture-analysis-2.rs:25:26
|
||||
|
|
||||
LL | println!("{:?}", p);
|
||||
| ^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/capture-analysis-2.rs:19:5
|
||||
|
|
||||
LL | / || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let _x = p.x;
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Min Capture p[] -> ByValue
|
||||
--> $DIR/capture-analysis-2.rs:22:18
|
||||
|
|
||||
LL | let _x = p.x;
|
||||
| ^^^ p[] captured as ByValue here
|
||||
...
|
||||
LL | println!("{:?}", p);
|
||||
| ^ p[] used here
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,35 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
//~| NOTE: `#[warn(incomplete_features)]` on by default
|
||||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Child {
|
||||
c: String,
|
||||
d: String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Parent {
|
||||
b: Child,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut a = Parent { b: Child {c: String::new(), d: String::new()} };
|
||||
|
||||
let c = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
||||
|| {
|
||||
//~^ First Pass analysis includes:
|
||||
//~| Min Capture analysis includes:
|
||||
let _x = a.b.c;
|
||||
//~^ NOTE: Capturing a[(0, 0),(0, 0)] -> ByValue
|
||||
//~| NOTE: a[(0, 0)] captured as ByValue here
|
||||
println!("{:?}", a.b);
|
||||
//~^ NOTE: Capturing a[(0, 0)] -> ImmBorrow
|
||||
//~| NOTE: Min Capture a[(0, 0)] -> ByValue
|
||||
//~| NOTE: a[(0, 0)] used here
|
||||
};
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/capture-analysis-3.rs:21:13
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/capture-analysis-3.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/capture-analysis-3.rs:24:5
|
||||
|
|
||||
LL | / || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let _x = a.b.c;
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Capturing a[(0, 0),(0, 0)] -> ByValue
|
||||
--> $DIR/capture-analysis-3.rs:27:18
|
||||
|
|
||||
LL | let _x = a.b.c;
|
||||
| ^^^^^
|
||||
note: Capturing a[(0, 0)] -> ImmBorrow
|
||||
--> $DIR/capture-analysis-3.rs:30:26
|
||||
|
|
||||
LL | println!("{:?}", a.b);
|
||||
| ^^^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/capture-analysis-3.rs:24:5
|
||||
|
|
||||
LL | / || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let _x = a.b.c;
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Min Capture a[(0, 0)] -> ByValue
|
||||
--> $DIR/capture-analysis-3.rs:27:18
|
||||
|
|
||||
LL | let _x = a.b.c;
|
||||
| ^^^^^ a[(0, 0)] captured as ByValue here
|
||||
...
|
||||
LL | println!("{:?}", a.b);
|
||||
| ^^^ a[(0, 0)] used here
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,33 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
//~| NOTE: `#[warn(incomplete_features)]` on by default
|
||||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Child {
|
||||
c: String,
|
||||
d: String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Parent {
|
||||
b: Child,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut a = Parent { b: Child {c: String::new(), d: String::new()} };
|
||||
|
||||
let c = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
||||
|| {
|
||||
//~^ First Pass analysis includes:
|
||||
//~| Min Capture analysis includes:
|
||||
let _x = a.b;
|
||||
//~^ NOTE: Capturing a[(0, 0)] -> ByValue
|
||||
//~| NOTE: Min Capture a[(0, 0)] -> ByValue
|
||||
println!("{:?}", a.b.c);
|
||||
//~^ NOTE: Capturing a[(0, 0),(0, 0)] -> ImmBorrow
|
||||
};
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/capture-analysis-4.rs:21:13
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/capture-analysis-4.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/capture-analysis-4.rs:24:5
|
||||
|
|
||||
LL | / || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let _x = a.b;
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Capturing a[(0, 0)] -> ByValue
|
||||
--> $DIR/capture-analysis-4.rs:27:18
|
||||
|
|
||||
LL | let _x = a.b;
|
||||
| ^^^
|
||||
note: Capturing a[(0, 0),(0, 0)] -> ImmBorrow
|
||||
--> $DIR/capture-analysis-4.rs:30:26
|
||||
|
|
||||
LL | println!("{:?}", a.b.c);
|
||||
| ^^^^^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/capture-analysis-4.rs:24:5
|
||||
|
|
||||
LL | / || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let _x = a.b;
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Min Capture a[(0, 0)] -> ByValue
|
||||
--> $DIR/capture-analysis-4.rs:27:18
|
||||
|
|
||||
LL | let _x = a.b;
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,52 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
//~| NOTE: `#[warn(incomplete_features)]` on by default
|
||||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(unused)]
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
#[derive(Debug)]
|
||||
struct Line {
|
||||
p: Point,
|
||||
q: Point
|
||||
}
|
||||
#[derive(Debug)]
|
||||
struct Plane {
|
||||
a: Line,
|
||||
b: Line,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut p = Plane {
|
||||
a: Line {
|
||||
p: Point { x: 1,y: 2 },
|
||||
q: Point { x: 3,y: 4 },
|
||||
},
|
||||
b: Line {
|
||||
p: Point { x: 1,y: 2 },
|
||||
q: Point { x: 3,y: 4 },
|
||||
}
|
||||
};
|
||||
|
||||
let c = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
||||
|| {
|
||||
//~^ ERROR: First Pass analysis includes:
|
||||
//~| ERROR: Min Capture analysis includes:
|
||||
let x = &p.a.p.x;
|
||||
//~^ NOTE: Capturing p[(0, 0),(0, 0),(0, 0)] -> ImmBorrow
|
||||
p.b.q.y = 9;
|
||||
//~^ NOTE: Capturing p[(1, 0),(1, 0),(1, 0)] -> MutBorrow
|
||||
//~| NOTE: p[] captured as MutBorrow here
|
||||
println!("{:?}", p);
|
||||
//~^ NOTE: Capturing p[] -> ImmBorrow
|
||||
//~| NOTE: Min Capture p[] -> MutBorrow
|
||||
//~| NOTE: p[] used here
|
||||
};
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/deep-multilevel-struct.rs:36:13
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/deep-multilevel-struct.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/deep-multilevel-struct.rs:39:5
|
||||
|
|
||||
LL | / || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let x = &p.a.p.x;
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Capturing p[(0, 0),(0, 0),(0, 0)] -> ImmBorrow
|
||||
--> $DIR/deep-multilevel-struct.rs:42:18
|
||||
|
|
||||
LL | let x = &p.a.p.x;
|
||||
| ^^^^^^^
|
||||
note: Capturing p[(1, 0),(1, 0),(1, 0)] -> MutBorrow
|
||||
--> $DIR/deep-multilevel-struct.rs:44:9
|
||||
|
|
||||
LL | p.b.q.y = 9;
|
||||
| ^^^^^^^
|
||||
note: Capturing p[] -> ImmBorrow
|
||||
--> $DIR/deep-multilevel-struct.rs:47:26
|
||||
|
|
||||
LL | println!("{:?}", p);
|
||||
| ^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/deep-multilevel-struct.rs:39:5
|
||||
|
|
||||
LL | / || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let x = &p.a.p.x;
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Min Capture p[] -> MutBorrow
|
||||
--> $DIR/deep-multilevel-struct.rs:44:9
|
||||
|
|
||||
LL | p.b.q.y = 9;
|
||||
| ^^^^^^^ p[] captured as MutBorrow here
|
||||
...
|
||||
LL | println!("{:?}", p);
|
||||
| ^ p[] used here
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,27 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
//~| NOTE: `#[warn(incomplete_features)]` on by default
|
||||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(unused)]
|
||||
|
||||
fn main() {
|
||||
let mut t = (((1,2),(3,4)),((5,6),(7,8)));
|
||||
|
||||
let c = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
||||
|| {
|
||||
//~^ ERROR: First Pass analysis includes:
|
||||
//~| ERROR: Min Capture analysis includes:
|
||||
let x = &t.0.0.0;
|
||||
//~^ NOTE: Capturing t[(0, 0),(0, 0),(0, 0)] -> ImmBorrow
|
||||
t.1.1.1 = 9;
|
||||
//~^ NOTE: Capturing t[(1, 0),(1, 0),(1, 0)] -> MutBorrow
|
||||
//~| NOTE: t[] captured as MutBorrow here
|
||||
println!("{:?}", t);
|
||||
//~^ NOTE: Min Capture t[] -> MutBorrow
|
||||
//~| NOTE: Capturing t[] -> ImmBorrow
|
||||
//~| NOTE: t[] used here
|
||||
};
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/deep-multilevel-tuple.rs:11:13
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/deep-multilevel-tuple.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/deep-multilevel-tuple.rs:14:5
|
||||
|
|
||||
LL | / || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let x = &t.0.0.0;
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Capturing t[(0, 0),(0, 0),(0, 0)] -> ImmBorrow
|
||||
--> $DIR/deep-multilevel-tuple.rs:17:18
|
||||
|
|
||||
LL | let x = &t.0.0.0;
|
||||
| ^^^^^^^
|
||||
note: Capturing t[(1, 0),(1, 0),(1, 0)] -> MutBorrow
|
||||
--> $DIR/deep-multilevel-tuple.rs:19:9
|
||||
|
|
||||
LL | t.1.1.1 = 9;
|
||||
| ^^^^^^^
|
||||
note: Capturing t[] -> ImmBorrow
|
||||
--> $DIR/deep-multilevel-tuple.rs:22:26
|
||||
|
|
||||
LL | println!("{:?}", t);
|
||||
| ^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/deep-multilevel-tuple.rs:14:5
|
||||
|
|
||||
LL | / || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let x = &t.0.0.0;
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Min Capture t[] -> MutBorrow
|
||||
--> $DIR/deep-multilevel-tuple.rs:19:9
|
||||
|
|
||||
LL | t.1.1.1 = 9;
|
||||
| ^^^^^^^ t[] captured as MutBorrow here
|
||||
...
|
||||
LL | println!("{:?}", t);
|
||||
| ^ t[] used here
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -32,9 +32,11 @@ fn main() {
|
|||
//~| ERROR: Min Capture analysis includes:
|
||||
p.x += 10;
|
||||
//~^ NOTE: Capturing p[(0, 0)] -> MutBorrow
|
||||
//~| NOTE: Min Capture p[] -> MutBorrow
|
||||
//~| NOTE: p[] captured as MutBorrow here
|
||||
println!("{:?}", p);
|
||||
//~^ NOTE: Capturing p[] -> ImmBorrow
|
||||
//~| NOTE: Min Capture p[] -> MutBorrow
|
||||
//~| NOTE: p[] used here
|
||||
};
|
||||
|
||||
c();
|
||||
|
|
|
@ -55,7 +55,10 @@ note: Min Capture p[] -> MutBorrow
|
|||
--> $DIR/simple-struct-min-capture.rs:33:9
|
||||
|
|
||||
LL | p.x += 10;
|
||||
| ^^^
|
||||
| ^^^ p[] captured as MutBorrow here
|
||||
...
|
||||
LL | println!("{:?}", p);
|
||||
| ^ p[] used here
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
// run-pass
|
||||
// Test that we use the elaborated predicates from traits
|
||||
// to satisfy const evaluatable predicates.
|
||||
#![feature(const_generics, const_evaluatable_checked)]
|
||||
#![allow(incomplete_features)]
|
||||
use std::mem::size_of;
|
||||
|
||||
trait Foo: Sized
|
||||
where
|
||||
[(); size_of::<Self>()]: Sized,
|
||||
{
|
||||
}
|
||||
|
||||
impl Foo for u64 {}
|
||||
impl Foo for u32 {}
|
||||
|
||||
fn foo<T: Foo>() -> [u8; size_of::<T>()] {
|
||||
[0; size_of::<T>()]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(foo::<u32>(), [0; 4]);
|
||||
assert_eq!(foo::<u64>(), [0; 8]);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// run-pass
|
||||
#![feature(const_generics, const_evaluatable_checked)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn callee<const M2: usize>() -> usize
|
||||
where
|
||||
[u8; M2 + 1]: Sized,
|
||||
{
|
||||
M2
|
||||
}
|
||||
|
||||
fn caller<const N1: usize>() -> usize
|
||||
where
|
||||
[u8; N1 + 1]: Sized,
|
||||
[u8; (N1 + 1) + 1]: Sized,
|
||||
{
|
||||
callee::<{ N1 + 1 }>()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(caller::<4>(), 5);
|
||||
}
|
||||
|
||||
// Test that the ``(N1 + 1) + 1`` bound on ``caller`` satisfies the ``M2 + 1`` bound on ``callee``
|
|
@ -0,0 +1,35 @@
|
|||
// run-pass
|
||||
#![feature(const_evaluatable_checked, const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct Generic<const K: u64>;
|
||||
|
||||
struct ConstU64<const K: u64>;
|
||||
|
||||
impl<const K: u64> Generic<K>
|
||||
where
|
||||
ConstU64<{ K - 1 }>: ,
|
||||
{
|
||||
fn foo(self) -> u64 {
|
||||
K
|
||||
}
|
||||
}
|
||||
|
||||
impl<const K: u64> Generic<K>
|
||||
where
|
||||
ConstU64<{ K - 1 }>: ,
|
||||
ConstU64<{ K + 1 }>: ,
|
||||
ConstU64<{ K + 1 - 1 }>: ,
|
||||
{
|
||||
fn bar(self) -> u64 {
|
||||
let x: Generic<{ K + 1 }> = Generic;
|
||||
x.foo()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!((Generic::<10>).bar(), 11);
|
||||
}
|
||||
|
||||
// Test that the ``ConstU64<{ K + 1 - 1}>`` bound on ``bar``'s impl block satisfies the
|
||||
// ``ConstU64<{K - 1}>`` bound on ``foo``'s impl block
|
|
@ -0,0 +1,35 @@
|
|||
// run-pass
|
||||
#![feature(const_generics, const_evaluatable_checked)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn zero_init<const N: usize>() -> Substs1<N>
|
||||
where
|
||||
[u8; N + 1]: ,
|
||||
{
|
||||
Substs1([0; N + 1])
|
||||
}
|
||||
struct Substs1<const N: usize>([u8; N + 1])
|
||||
where
|
||||
[(); N + 1]: ;
|
||||
|
||||
fn substs2<const M: usize>() -> Substs1<{ M * 2 }>
|
||||
where
|
||||
[(); { M * 2 } + 1]: ,
|
||||
{
|
||||
zero_init::<{ M * 2 }>()
|
||||
}
|
||||
|
||||
fn substs3<const L: usize>() -> Substs1<{ (L - 1) * 2 }>
|
||||
where
|
||||
[(); (L - 1)]: ,
|
||||
[(); (L - 1) * 2 + 1]: ,
|
||||
{
|
||||
substs2::<{ L - 1 }>()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(substs3::<2>().0, [0; 3]);
|
||||
}
|
||||
|
||||
// Test that the ``{ (L - 1) * 2 + 1 }`` bound on ``substs3`` satisfies the
|
||||
// ``{ N + 1 }`` bound on ``Substs1``
|
|
@ -0,0 +1,29 @@
|
|||
// run-pass
|
||||
#![feature(const_generics, const_evaluatable_checked)]
|
||||
#![allow(incomplete_features, unused_parens, unused_braces)]
|
||||
|
||||
fn zero_init<const N: usize>() -> Substs1<{ (N) }>
|
||||
where
|
||||
[u8; { (N) }]: ,
|
||||
{
|
||||
Substs1([0; { (N) }])
|
||||
}
|
||||
|
||||
struct Substs1<const N: usize>([u8; { (N) }])
|
||||
where
|
||||
[(); { (N) }]: ;
|
||||
|
||||
fn substs2<const M: usize>() -> Substs1<{ (M) }> {
|
||||
zero_init::<{ (M) }>()
|
||||
}
|
||||
|
||||
fn substs3<const L: usize>() -> Substs1<{ (L) }> {
|
||||
substs2::<{ (L) }>()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(substs3::<2>().0, [0; 2]);
|
||||
}
|
||||
|
||||
// Test that the implicit ``{ (L) }`` bound on ``substs3`` satisfies the
|
||||
// ``{ (N) }`` bound on ``Substs1``
|
|
@ -1,9 +1,15 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/simple_fail.rs:9:48
|
||||
|
|
||||
LL | fn test<const N: usize>() -> Arr<N> where [u8; N - 1]: Sized {
|
||||
| ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/simple_fail.rs:6:33
|
||||
|
|
||||
LL | type Arr<const N: usize> = [u8; N - 1];
|
||||
| ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
|
||||
|
||||
error: aborting due to previous error
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
|
|
|
@ -7,5 +7,14 @@ LL | type Arr<const N: usize> = [u8; N - 1];
|
|||
= help: const parameters may only be used as standalone arguments, i.e. `N`
|
||||
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
|
||||
|
||||
error: aborting due to previous error
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/simple_fail.rs:9:48
|
||||
|
|
||||
LL | fn test<const N: usize>() -> Arr<N> where [u8; N - 1]: Sized {
|
||||
| ^ cannot perform const operation using `N`
|
||||
|
|
||||
= help: const parameters may only be used as standalone arguments, i.e. `N`
|
||||
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
// revisions: full min
|
||||
#![cfg_attr(full, feature(const_generics))]
|
||||
#![feature(const_evaluatable_checked)]
|
||||
#![cfg_attr(full, feature(const_evaluatable_checked))]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
type Arr<const N: usize> = [u8; N - 1]; //[full]~ ERROR evaluation of constant
|
||||
//[min]~^ ERROR generic parameters may not be used in const operations
|
||||
|
||||
fn test<const N: usize>() -> Arr<N> where Arr<N>: Sized {
|
||||
fn test<const N: usize>() -> Arr<N> where [u8; N - 1]: Sized {
|
||||
//[min]~^ ERROR generic parameters may not be used in const operations
|
||||
//[full]~^^ ERROR evaluation of constant
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// check-pass
|
||||
// Test that we correctly substitute generic arguments for type aliases.
|
||||
#![feature(const_generics, const_evaluatable_checked)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
type Alias<T, const N: usize> = [T; N + 1];
|
||||
|
||||
fn foo<const M: usize>() -> Alias<u32, M> where [u8; M + 1]: Sized {
|
||||
[0; M + 1]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo::<0>();
|
||||
}
|
|
@ -32,12 +32,12 @@ LL | Struct { a, _ } = Struct { a: 1, b: 2 };
|
|||
|
|
||||
help: include the missing field in the pattern
|
||||
|
|
||||
LL | Struct { a, b _ } = Struct { a: 1, b: 2 };
|
||||
| ^^^
|
||||
LL | Struct { a, b } = Struct { a: 1, b: 2 };
|
||||
| ^^^^^
|
||||
help: if you don't care about this missing field, you can explicitly ignore it
|
||||
|
|
||||
LL | Struct { a, .. _ } = Struct { a: 1, b: 2 };
|
||||
| ^^^^
|
||||
LL | Struct { a, .. } = Struct { a: 1, b: 2 };
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
|
@ -7,11 +7,11 @@ LL | Dog { age: x } => {}
|
|||
help: include the missing field in the pattern
|
||||
|
|
||||
LL | Dog { age: x, name } => {}
|
||||
| ^^^^^^
|
||||
| ^^^^^^^^
|
||||
help: if you don't care about this missing field, you can explicitly ignore it
|
||||
|
|
||||
LL | Dog { age: x, .. } => {}
|
||||
| ^^^^
|
||||
| ^^^^^^
|
||||
|
||||
error[E0027]: pattern does not mention field `age`
|
||||
--> $DIR/E0027.rs:15:9
|
||||
|
@ -22,11 +22,11 @@ LL | Dog { name: x, } => {}
|
|||
help: include the missing field in the pattern
|
||||
|
|
||||
LL | Dog { name: x, age } => {}
|
||||
| ^^^^^
|
||||
| ^^^^^^^
|
||||
help: if you don't care about this missing field, you can explicitly ignore it
|
||||
|
|
||||
LL | Dog { name: x, .. } => {}
|
||||
| ^^^^
|
||||
| ^^^^^^
|
||||
|
||||
error[E0027]: pattern does not mention field `age`
|
||||
--> $DIR/E0027.rs:19:9
|
||||
|
@ -37,11 +37,11 @@ LL | Dog { name: x , } => {}
|
|||
help: include the missing field in the pattern
|
||||
|
|
||||
LL | Dog { name: x, age } => {}
|
||||
| ^^^^^
|
||||
| ^^^^^^^
|
||||
help: if you don't care about this missing field, you can explicitly ignore it
|
||||
|
|
||||
LL | Dog { name: x, .. } => {}
|
||||
| ^^^^
|
||||
| ^^^^^^
|
||||
|
||||
error[E0027]: pattern does not mention fields `name`, `age`
|
||||
--> $DIR/E0027.rs:22:9
|
||||
|
|
|
@ -19,11 +19,11 @@ LL | let A { x, y } = self.d;
|
|||
help: include the missing fields in the pattern
|
||||
|
|
||||
LL | let A { x, y, b, c } = self.d;
|
||||
| ^^^^^^
|
||||
| ^^^^^^^^
|
||||
help: if you don't care about these missing fields, you can explicitly ignore them
|
||||
|
|
||||
LL | let A { x, y, .. } = self.d;
|
||||
| ^^^^
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 783bc43c660bf39c1e562c8c429b32078ad3099b
|
||||
Subproject commit c3abcfe8a75901c7c701557a728941e8fb19399e
|
|
@ -2,11 +2,10 @@ use crate::utils::{
|
|||
contains_name, get_pat_name, match_type, paths, single_segment_path, snippet_with_applicability, span_lint_and_sugg,
|
||||
};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::UintTy;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, UnOp};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::{self, UintTy};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::sym;
|
||||
use rustc_span::Symbol;
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
use crate::utils::{clip, sext, unsext};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
|
||||
use rustc_ast::ast::{self, LitFloatType, LitKind};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::{BinOp, BinOpKind, Block, Expr, ExprKind, HirId, QPath, UnOp};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::mir::interpret::Scalar;
|
||||
use rustc_middle::ty::subst::{Subst, SubstsRef};
|
||||
use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, FloatTy, ScalarInt, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::symbol::Symbol;
|
||||
use std::cmp::Ordering::{self, Equal};
|
||||
|
@ -167,8 +167,8 @@ pub fn lit_to_constant(lit: &LitKind, ty: Option<Ty<'_>>) -> Constant {
|
|||
LitKind::Char(c) => Constant::Char(c),
|
||||
LitKind::Int(n, _) => Constant::Int(n),
|
||||
LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty {
|
||||
FloatTy::F32 => Constant::F32(is.as_str().parse().unwrap()),
|
||||
FloatTy::F64 => Constant::F64(is.as_str().parse().unwrap()),
|
||||
ast::FloatTy::F32 => Constant::F32(is.as_str().parse().unwrap()),
|
||||
ast::FloatTy::F64 => Constant::F64(is.as_str().parse().unwrap()),
|
||||
},
|
||||
LitKind::Float(ref is, LitFloatType::Unsuffixed) => match ty.expect("type of float is known").kind() {
|
||||
ty::Float(FloatTy::F32) => Constant::F32(is.as_str().parse().unwrap()),
|
||||
|
|
|
@ -3,10 +3,9 @@
|
|||
|
||||
use crate::consts::{miri_to_const, Constant};
|
||||
use crate::utils::span_lint;
|
||||
use rustc_ast::ast::{IntTy, UintTy};
|
||||
use rustc_hir::{Item, ItemKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::{self, IntTy, UintTy};
|
||||
use rustc_middle::ty::util::IntTypeExt;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use std::convert::TryFrom;
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
use crate::utils::paths::FROM_TRAIT;
|
||||
use crate::utils::{
|
||||
is_expn_of, is_type_diagnostic_item, match_def_path, match_panic_def_id, method_chain_args, span_lint_and_then,
|
||||
};
|
||||
use crate::utils::{is_expn_of, is_type_diagnostic_item, match_panic_def_id, method_chain_args, span_lint_and_then};
|
||||
use if_chain::if_chain;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
@ -59,7 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for FallibleImplFrom {
|
|||
if_chain! {
|
||||
if let hir::ItemKind::Impl(impl_) = &item.kind;
|
||||
if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(impl_def_id);
|
||||
if match_def_path(cx, impl_trait_ref.def_id, &FROM_TRAIT);
|
||||
if cx.tcx.is_diagnostic_item(sym::from_trait, impl_trait_ref.def_id);
|
||||
then {
|
||||
lint_impl_body(cx, item.span, impl_.items);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use crate::utils::{numeric_literal, span_lint_and_sugg};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
|
||||
use rustc_ast::ast::{self, LitFloatType, LitKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::{self, FloatTy};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use std::fmt;
|
||||
|
||||
|
@ -75,8 +75,8 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral {
|
|||
let digits = count_digits(&sym_str);
|
||||
let max = max_digits(fty);
|
||||
let type_suffix = match lit_float_ty {
|
||||
LitFloatType::Suffixed(FloatTy::F32) => Some("f32"),
|
||||
LitFloatType::Suffixed(FloatTy::F64) => Some("f64"),
|
||||
LitFloatType::Suffixed(ast::FloatTy::F32) => Some("f32"),
|
||||
LitFloatType::Suffixed(ast::FloatTy::F64) => Some("f64"),
|
||||
LitFloatType::Unsuffixed => None
|
||||
};
|
||||
let (is_whole, mut float_str) = match fty {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
//! This lint is **warn** by default
|
||||
|
||||
use crate::utils::{is_type_diagnostic_item, span_lint};
|
||||
use rustc_ast::ast;
|
||||
use rustc_hir::Expr;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
|
@ -77,8 +76,8 @@ impl<'tcx> LateLintPass<'tcx> for Mutex {
|
|||
atomic_name
|
||||
);
|
||||
match *mutex_param.kind() {
|
||||
ty::Uint(t) if t != ast::UintTy::Usize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
|
||||
ty::Int(t) if t != ast::IntTy::Isize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
|
||||
ty::Uint(t) if t != ty::UintTy::Usize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
|
||||
ty::Int(t) if t != ty::IntTy::Isize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
|
||||
_ => span_lint(cx, MUTEX_ATOMIC, expr.span, &msg),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -443,7 +443,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
|
|||
);
|
||||
},
|
||||
),
|
||||
(ty::Int(ast::IntTy::I32) | ty::Uint(ast::UintTy::U32), &ty::Char) => {
|
||||
(ty::Int(ty::IntTy::I32) | ty::Uint(ty::UintTy::U32), &ty::Char) => {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
TRANSMUTE_INT_TO_CHAR,
|
||||
|
@ -468,7 +468,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
|
|||
(ty::Ref(_, ty_from, from_mutbl), ty::Ref(_, ty_to, to_mutbl)) => {
|
||||
if_chain! {
|
||||
if let (&ty::Slice(slice_ty), &ty::Str) = (&ty_from.kind(), &ty_to.kind());
|
||||
if let ty::Uint(ast::UintTy::U8) = slice_ty.kind();
|
||||
if let ty::Uint(ty::UintTy::U8) = slice_ty.kind();
|
||||
if from_mutbl == to_mutbl;
|
||||
then {
|
||||
let postfix = if *from_mutbl == Mutability::Mut {
|
||||
|
@ -536,7 +536,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
|
|||
}
|
||||
},
|
||||
),
|
||||
(ty::Int(ast::IntTy::I8) | ty::Uint(ast::UintTy::U8), ty::Bool) => {
|
||||
(ty::Int(ty::IntTy::I8) | ty::Uint(ty::UintTy::U8), ty::Bool) => {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
TRANSMUTE_INT_TO_BOOL,
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::cmp::Ordering;
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::{FloatTy, IntTy, LitFloatType, LitIntType, LitKind, UintTy};
|
||||
use rustc_ast::{LitFloatType, LitIntType, LitKind};
|
||||
use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisitorMap, Visitor};
|
||||
|
@ -18,7 +18,7 @@ use rustc_lint::{LateContext, LateLintPass, LintContext};
|
|||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::TypeFoldable;
|
||||
use rustc_middle::ty::{self, InferTy, Ty, TyCtxt, TyS, TypeAndMut, TypeckResults};
|
||||
use rustc_middle::ty::{self, FloatTy, InferTy, IntTy, Ty, TyCtxt, TyS, TypeAndMut, TypeckResults, UintTy};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::hygiene::{ExpnKind, MacroKind};
|
||||
|
@ -1106,9 +1106,7 @@ fn is_empty_block(expr: &Expr<'_>) -> bool {
|
|||
expr.kind,
|
||||
ExprKind::Block(
|
||||
Block {
|
||||
stmts: &[],
|
||||
expr: None,
|
||||
..
|
||||
stmts: &[], expr: None, ..
|
||||
},
|
||||
_,
|
||||
)
|
||||
|
|
|
@ -35,7 +35,6 @@ use std::mem;
|
|||
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::{self, Attribute, LitKind};
|
||||
use rustc_attr as attr;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
|
@ -1224,27 +1223,27 @@ pub fn get_arg_name(pat: &Pat<'_>) -> Option<Symbol> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn int_bits(tcx: TyCtxt<'_>, ity: ast::IntTy) -> u64 {
|
||||
Integer::from_attr(&tcx, attr::IntType::SignedInt(ity)).size().bits()
|
||||
pub fn int_bits(tcx: TyCtxt<'_>, ity: ty::IntTy) -> u64 {
|
||||
Integer::from_int_ty(&tcx, ity).size().bits()
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
/// Turn a constant int byte representation into an i128
|
||||
pub fn sext(tcx: TyCtxt<'_>, u: u128, ity: ast::IntTy) -> i128 {
|
||||
pub fn sext(tcx: TyCtxt<'_>, u: u128, ity: ty::IntTy) -> i128 {
|
||||
let amt = 128 - int_bits(tcx, ity);
|
||||
((u as i128) << amt) >> amt
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
/// clip unused bytes
|
||||
pub fn unsext(tcx: TyCtxt<'_>, u: i128, ity: ast::IntTy) -> u128 {
|
||||
pub fn unsext(tcx: TyCtxt<'_>, u: i128, ity: ty::IntTy) -> u128 {
|
||||
let amt = 128 - int_bits(tcx, ity);
|
||||
((u as u128) << amt) >> amt
|
||||
}
|
||||
|
||||
/// clip unused bytes
|
||||
pub fn clip(tcx: TyCtxt<'_>, u: u128, ity: ast::UintTy) -> u128 {
|
||||
let bits = Integer::from_attr(&tcx, attr::IntType::UnsignedInt(ity)).size().bits();
|
||||
pub fn clip(tcx: TyCtxt<'_>, u: u128, ity: ty::UintTy) -> u128 {
|
||||
let bits = Integer::from_uint_ty(&tcx, ity).size().bits();
|
||||
let amt = 128 - bits;
|
||||
(u << amt) >> amt
|
||||
}
|
||||
|
|
|
@ -48,7 +48,6 @@ pub const FN_MUT: [&str; 3] = ["core", "ops", "FnMut"];
|
|||
pub const FN_ONCE: [&str; 3] = ["core", "ops", "FnOnce"];
|
||||
pub const FROM_FROM: [&str; 4] = ["core", "convert", "From", "from"];
|
||||
pub const FROM_ITERATOR: [&str; 5] = ["core", "iter", "traits", "collect", "FromIterator"];
|
||||
pub const FROM_TRAIT: [&str; 3] = ["core", "convert", "From"];
|
||||
pub const FUTURE_FROM_GENERATOR: [&str; 3] = ["core", "future", "from_generator"];
|
||||
pub const HASH: [&str; 3] = ["core", "hash", "Hash"];
|
||||
pub const HASHMAP: [&str; 5] = ["std", "collections", "hash", "map", "HashMap"];
|
||||
|
|
|
@ -174,7 +174,7 @@ impl fmt::Display for Debugger {
|
|||
/// Configuration for compiletest
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Config {
|
||||
/// `true` to to overwrite stderr/stdout files instead of complaining about changes in output.
|
||||
/// `true` to overwrite stderr/stdout files instead of complaining about changes in output.
|
||||
pub bless: bool,
|
||||
|
||||
/// The library paths required for running the compiler.
|
||||
|
|
|
@ -30,3 +30,22 @@ fn test_matches_os() {
|
|||
assert!(matches_os("nvptx64-nvidia-cuda", "cuda"));
|
||||
assert!(matches_os("x86_64-fortanix-unknown-sgx", "sgx"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_big_endian_test() {
|
||||
assert!(!is_big_endian("no"));
|
||||
assert!(is_big_endian("sparc-unknown-unknown"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_buf_with_extra_extension_test() {
|
||||
assert_eq!(
|
||||
PathBuf::from("foo.rs.stderr"),
|
||||
PathBuf::from("foo.rs").with_extra_extension("stderr")
|
||||
);
|
||||
assert_eq!(
|
||||
PathBuf::from("foo.rs.stderr"),
|
||||
PathBuf::from("foo.rs").with_extra_extension(".stderr")
|
||||
);
|
||||
assert_eq!(PathBuf::from("foo.rs"), PathBuf::from("foo.rs").with_extra_extension(""));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue