diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2e51a786f4682..49961d02ddab7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -566,7 +566,7 @@ labels to triage issues: to fix the issue. * The dark blue **final-comment-period** label marks bugs that are using the - RFC signoff functionality of [rfcbot][rfcbot] and are currenty in the final + RFC signoff functionality of [rfcbot][rfcbot] and are currently in the final comment period. * Red, **I**-prefixed labels indicate the **importance** of the issue. The diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index e845438c0a836..2bc037e3fee12 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1822,12 +1822,12 @@ impl SpecExtend for Vec unsafe { let mut ptr = self.as_mut_ptr().add(self.len()); let mut local_len = SetLenOnDrop::new(&mut self.len); - for element in iterator { + iterator.for_each(move |element| { ptr::write(ptr, element); ptr = ptr.offset(1); // NB can't overflow since we would have had to alloc the address space local_len.increment_len(1); - } + }); } } else { self.extend_desugared(iterator) diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 2a38464d7c1ee..7d87c1839d78c 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -288,7 +288,7 @@ impl<'a> Parser<'a> { self.cur.next(); Some(pos) } else { - let pos = pos + padding + 1; + let pos = pos + raw + 1; self.err(format!("expected `{:?}`, found `{:?}`", c, maybe), format!("expected `{}`", c), pos, diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 9c4e995e24d01..388abc88cfd71 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -873,8 +873,8 @@ for ty::TyKind<'gcx> Tuple(inner_tys) => { inner_tys.hash_stable(hcx, hasher); } - Projection(ref projection_ty) => { - projection_ty.hash_stable(hcx, hasher); + Projection(ref data) | UnnormalizedProjection(ref data) => { + data.hash_stable(hcx, hasher); } Opaque(def_id, substs) => { def_id.hash_stable(hcx, hasher); diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs index b30ccb5976c98..6449227af4ab8 100644 --- a/src/librustc/infer/canonical/canonicalizer.rs +++ b/src/librustc/infer/canonical/canonicalizer.rs @@ -283,6 +283,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> | ty::Never | ty::Tuple(..) | ty::Projection(..) + | ty::UnnormalizedProjection(..) | ty::Foreign(..) | ty::Param(..) | ty::Opaque(..) => { diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index 1cb813c39e68c..e17e777332ec6 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -193,6 +193,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { ty::Never | ty::Tuple(..) | ty::Projection(..) | + ty::UnnormalizedProjection(..) | ty::Foreign(..) | ty::Param(..) | ty::Closure(..) | diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index d695ad88e47aa..c81d55e69b61a 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -171,7 +171,7 @@ impl<'tcx> Scalar { pub fn from_uint(i: impl Into, size: Size) -> Self { let i = i.into(); debug_assert_eq!(truncate(i, size), i, - "Unsigned value {} does not fit in {} bits", i, size.bits()); + "Unsigned value {} does not fit in {} bits", i, size.bits()); Scalar::Bits { bits: i, size: size.bytes() as u8 } } @@ -181,7 +181,7 @@ impl<'tcx> Scalar { // `into` performed sign extension, we have to truncate let truncated = truncate(i as u128, size); debug_assert_eq!(sign_extend(truncated, size) as i128, i, - "Signed value {} does not fit in {} bits", i, size.bits()); + "Signed value {} does not fit in {} bits", i, size.bits()); Scalar::Bits { bits: truncated, size: size.bytes() as u8 } } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 27ef01b93cda1..30117f90dc69f 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -12,7 +12,6 @@ //! //! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/index.html -use graphviz::IntoCow; use hir::def::CtorKind; use hir::def_id::DefId; use hir::{self, HirId, InlineAsm}; @@ -327,22 +326,20 @@ impl<'tcx> Mir<'tcx> { if idx < stmts.len() { &stmts[idx].source_info } else { - assert!(idx == stmts.len()); + assert_eq!(idx, stmts.len()); &block.terminator().source_info } } /// Check if `sub` is a sub scope of `sup` pub fn is_sub_scope(&self, mut sub: SourceScope, sup: SourceScope) -> bool { - loop { - if sub == sup { - return true; - } + while sub != sup { match self.source_scopes[sub].parent_scope { None => return false, Some(p) => sub = p, } } + true } /// Return the return type, it always return first element from `local_decls` array @@ -526,9 +523,7 @@ impl BorrowKind { pub fn allows_two_phase_borrow(&self) -> bool { match *self { BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => false, - BorrowKind::Mut { - allow_two_phase_borrow, - } => allow_two_phase_borrow, + BorrowKind::Mut { allow_two_phase_borrow } => allow_two_phase_borrow, } } } @@ -1574,42 +1569,42 @@ impl<'tcx> TerminatorKind<'tcx> { }; fmt_const_val(&mut s, &c).unwrap(); s.into() - }).chain(iter::once(String::from("otherwise").into())) + }).chain(iter::once("otherwise".into())) .collect() } Call { destination: Some(_), cleanup: Some(_), .. - } => vec!["return".into_cow(), "unwind".into_cow()], + } => vec!["return".into(), "unwind".into()], Call { destination: Some(_), cleanup: None, .. - } => vec!["return".into_cow()], + } => vec!["return".into()], Call { destination: None, cleanup: Some(_), .. - } => vec!["unwind".into_cow()], + } => vec!["unwind".into()], Call { destination: None, cleanup: None, .. } => vec![], - Yield { drop: Some(_), .. } => vec!["resume".into_cow(), "drop".into_cow()], - Yield { drop: None, .. } => vec!["resume".into_cow()], + Yield { drop: Some(_), .. } => vec!["resume".into(), "drop".into()], + Yield { drop: None, .. } => vec!["resume".into()], DropAndReplace { unwind: None, .. } | Drop { unwind: None, .. } => { - vec!["return".into_cow()] + vec!["return".into()] } DropAndReplace { unwind: Some(_), .. } | Drop { unwind: Some(_), .. - } => vec!["return".into_cow(), "unwind".into_cow()], + } => vec!["return".into(), "unwind".into()], Assert { cleanup: None, .. } => vec!["".into()], - Assert { .. } => vec!["success".into_cow(), "unwind".into_cow()], + Assert { .. } => vec!["success".into(), "unwind".into()], FalseEdges { ref imaginary_targets, .. diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 4d353a36db02a..7520695a7cd90 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -325,7 +325,7 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a> CodegenUnitNameBuilder<'a, 'gcx, 'tcx> { String::new() }; - let crate_disambiguator = format!("{}", tcx.crate_disambiguator(cnum)); + let crate_disambiguator = tcx.crate_disambiguator(cnum).to_string(); // Using a shortened disambiguator of about 40 bits format!("{}.{}{}", tcx.crate_name(cnum), diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 2a25e057a7149..fc7b4862b0ae5 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -87,8 +87,8 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { assert!(index < adt_def.variants.len()); assert_eq!(adt_def, adt_def1); PlaceTy::Downcast { adt_def, - substs, - variant_index: index } + substs, + variant_index: index } } _ => { bug!("cannot downcast non-ADT type: `{:?}`", self) @@ -151,7 +151,7 @@ impl<'tcx> Place<'tcx> { } }, _ => None, - } + } _ => None, } } @@ -255,9 +255,9 @@ impl<'tcx> Operand<'tcx> { impl<'tcx> BinOp { pub fn ty<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - lhs_ty: Ty<'tcx>, - rhs_ty: Ty<'tcx>) - -> Ty<'tcx> { + lhs_ty: Ty<'tcx>, + rhs_ty: Ty<'tcx>) + -> Ty<'tcx> { // FIXME: handle SIMD correctly match self { &BinOp::Add | &BinOp::Sub | &BinOp::Mul | &BinOp::Div | &BinOp::Rem | diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 7401d4099ff6d..caf549e37a907 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -475,6 +475,7 @@ fn ty_is_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> bool { ty::Error => true, + ty::UnnormalizedProjection(..) | ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) | diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 7695f26d70115..3b3e38a8bb7ca 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -269,7 +269,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ty::Generator(..) => Some(18), ty::Foreign(..) => Some(19), ty::GeneratorWitness(..) => Some(20), - ty::Infer(..) | ty::Error => None + ty::Infer(..) | ty::Error => None, + ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), } } diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index f5fb183ec1a5d..aaf03f8e7fb55 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -253,5 +253,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'_, '_, 'tcx>, ty: Ty<'tcx>) -> | ty::Opaque(..) | ty::Infer(_) | ty::Generator(..) => false, + + ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), } } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 860914d1984ec..c9fa960a36561 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2283,6 +2283,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => None, ty::Infer(ty::TyVar(_)) => Ambiguous, + ty::UnnormalizedProjection(..) | ty::Infer(ty::CanonicalTy(_)) | ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) | @@ -2355,6 +2356,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { Ambiguous } + ty::UnnormalizedProjection(..) | ty::Infer(ty::CanonicalTy(_)) | ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) | @@ -2393,6 +2395,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { Vec::new() } + ty::UnnormalizedProjection(..) | ty::Dynamic(..) | ty::Param(..) | ty::Foreign(..) | diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 85559c892c4af..05b68b34989bf 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2234,7 +2234,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { self, Adt, Array, Slice, RawPtr, Ref, FnDef, FnPtr, Generator, GeneratorWitness, Dynamic, Closure, Tuple, - Param, Infer, Projection, Opaque, Foreign); + Param, Infer, UnnormalizedProjection, Projection, Opaque, Foreign); println!("Substs interner: #{}", self.interners.substs.borrow().len()); println!("Region interner: #{}", self.interners.region.borrow().len()); diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 9f9d918415e7e..b3a1b312ca1d3 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -222,6 +222,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::Infer(ty::FreshIntTy(_)) => "skolemized integral type".to_string(), ty::Infer(ty::FreshFloatTy(_)) => "skolemized floating-point type".to_string(), ty::Projection(_) => "associated type".to_string(), + ty::UnnormalizedProjection(_) => "non-normalized associated type".to_string(), ty::Param(ref p) => { if p.is_self() { "Self".to_string() diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 2d055fd307dc4..0f68e7aba4def 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -103,6 +103,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, ty::FnPtr(ref f) => { Some(FunctionSimplifiedType(f.skip_binder().inputs().len())) } + ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), ty::Projection(_) | ty::Param(_) => { if can_simplify_params { // In normalized types, projections don't unify with diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 08d1057823873..3ccc24e73a5c9 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -150,6 +150,8 @@ impl FlagComputation { self.add_projection_ty(data); } + &ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), + &ty::Opaque(_, substs) => { self.add_flags(TypeFlags::HAS_PROJECTION); self.add_substs(substs); diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index c8d104e6c321f..46d133224f819 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -463,6 +463,7 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { ty::Str | ty::FnPtr(_) | ty::Projection(_) | + ty::UnnormalizedProjection(..) | ty::Param(_) | ty::Opaque(..) | ty::Infer(_) | diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 8bfe46568eb19..7df8af5fa2e7d 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1123,7 +1123,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } tcx.layout_raw(param_env.and(normalized))? } - ty::GeneratorWitness(..) | ty::Infer(_) => { + ty::UnnormalizedProjection(..) | ty::GeneratorWitness(..) | ty::Infer(_) => { bug!("LayoutDetails::compute: unexpected type `{}`", ty) } ty::Param(_) | ty::Error => { @@ -1702,8 +1702,8 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx> } } - ty::Projection(_) | ty::Opaque(..) | ty::Param(_) | - ty::Infer(_) | ty::Error => { + ty::Projection(_) | ty::UnnormalizedProjection(..) | + ty::Opaque(..) | ty::Param(_) | ty::Infer(_) | ty::Error => { bug!("TyLayout::field_type: unexpected type `{}`", this.ty) } }) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 57afbafc2a5f6..72232084bf7ea 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2340,6 +2340,8 @@ impl<'a, 'gcx, 'tcx> AdtDef { vec![ty] } + UnnormalizedProjection(..) => bug!("only used with chalk-engine"), + Param(..) => { // perf hack: if there is a `T: Sized` bound, then // we know that `T` is Sized and do not need to check diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index 68f6707087687..91eda66e08c6e 100644 --- a/src/librustc/ty/outlives.rs +++ b/src/librustc/ty/outlives.rs @@ -124,6 +124,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } + ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), + // We assume that inference variables are fully resolved. // So, if we encounter an inference variable, just record // the unresolved variable as a component. diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index aab268c07c4fb..c3c4cbed89d88 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -876,6 +876,9 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::GeneratorWitness(types) => ty::GeneratorWitness(types.fold_with(folder)), ty::Closure(did, substs) => ty::Closure(did, substs.fold_with(folder)), ty::Projection(ref data) => ty::Projection(data.fold_with(folder)), + ty::UnnormalizedProjection(ref data) => { + ty::UnnormalizedProjection(data.fold_with(folder)) + } ty::Opaque(did, substs) => ty::Opaque(did, substs.fold_with(folder)), ty::Bool | ty::Char | ty::Str | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Error | ty::Infer(_) | @@ -910,7 +913,9 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { } ty::GeneratorWitness(ref types) => types.visit_with(visitor), ty::Closure(_did, ref substs) => substs.visit_with(visitor), - ty::Projection(ref data) => data.visit_with(visitor), + ty::Projection(ref data) | ty::UnnormalizedProjection(ref data) => { + data.visit_with(visitor) + } ty::Opaque(_, ref substs) => substs.visit_with(visitor), ty::Bool | ty::Char | ty::Str | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Error | ty::Infer(_) | diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 6c40dd8923916..06d559fd9dbea 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -157,6 +157,11 @@ pub enum TyKind<'tcx> { /// `>::N`. Projection(ProjectionTy<'tcx>), + /// A placeholder type used when we do not have enough information + /// to normalize the projection of an associated type to an + /// existing concrete type. Currently only used with chalk-engine. + UnnormalizedProjection(ProjectionTy<'tcx>), + /// Opaque (`impl Trait`) type found in a return type. /// The `DefId` comes either from /// * the `impl Trait` ast::Ty node, @@ -1806,7 +1811,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { Generator(_, GeneratorSubsts { ref substs }, _) => { substs.regions().collect() } - Projection(ref data) => { + Projection(ref data) | UnnormalizedProjection(ref data) => { data.substs.regions().collect() } FnDef(..) | @@ -1886,6 +1891,8 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => false, + ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), + ty::Infer(ty::TyVar(_)) => false, ty::Infer(ty::CanonicalTy(_)) | diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 93fc77359e43a..4d7bab3cf433b 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -958,6 +958,8 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::Dynamic(..) | ty::Projection(..) | ty::Param(_) | ty::Opaque(..) | ty::Infer(_) | ty::Error => true, + ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), + // Structural recursion. ty::Array(ty, _) | ty::Slice(ty) => needs_drop(ty), diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index cf87c2d457471..d20c4f716429b 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -97,7 +97,7 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { ty::Ref(_, ty, _) => { stack.push(ty); } - ty::Projection(ref data) => { + ty::Projection(ref data) | ty::UnnormalizedProjection(ref data) => { stack.extend(data.substs.types().rev()); } ty::Dynamic(ref obj, ..) => { diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 63206a660df41..397c63a149a4c 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -289,6 +289,8 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { self.compute_projection(data); } + ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), + ty::Adt(def, substs) => { // WfNominalType let obligations = self.nominal_obligations(def.did, substs); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 10382008e0d43..814f8880bbf2f 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -18,7 +18,7 @@ use ty::{Bool, Char, Adt}; use ty::{Error, Str, Array, Slice, Float, FnDef, FnPtr}; use ty::{Param, RawPtr, Ref, Never, Tuple}; use ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque}; -use ty::{Dynamic, Int, Uint, Infer}; +use ty::{UnnormalizedProjection, Dynamic, Int, Uint, Infer}; use ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind}; use util::nodemap::FxHashSet; @@ -1143,6 +1143,11 @@ define_print! { } Foreign(def_id) => parameterized(f, subst::Substs::empty(), def_id, &[]), Projection(ref data) => data.print(f, cx), + UnnormalizedProjection(ref data) => { + write!(f, "Unnormalized(")?; + data.print(f, cx)?; + write!(f, ")") + } Opaque(def_id, substs) => { if cx.is_verbose { return write!(f, "Opaque({:?}, {:?})", def_id, substs); diff --git a/src/librustc_codegen_llvm/debuginfo/type_names.rs b/src/librustc_codegen_llvm/debuginfo/type_names.rs index f9eb80a1988af..2f110fd552a8d 100644 --- a/src/librustc_codegen_llvm/debuginfo/type_names.rs +++ b/src/librustc_codegen_llvm/debuginfo/type_names.rs @@ -173,6 +173,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } ty::Error | ty::Infer(_) | + ty::UnnormalizedProjection(..) | ty::Projection(..) | ty::Opaque(..) | ty::GeneratorWitness(..) | diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 01d4d0f8cdb67..a441f7a87f763 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -722,6 +722,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) | + ty::UnnormalizedProjection(..) | ty::Projection(..) | ty::Opaque(..) | ty::FnDef(..) => bug!("Unexpected type in foreign function"), diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 7a9d18676cf6c..ae178888b6a1c 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -65,9 +65,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { ty::Adt(def, _) => { if def.variants.is_empty() { return; - } else { - check_must_use(cx, def.did, s.span, "") } + check_must_use(cx, def.did, s.span, "") }, _ => false, }; @@ -337,21 +336,13 @@ impl EarlyLintPass for UnusedParens { AssignOp(.., ref value) => (value, "assigned value", false), // either function/method call, or something this lint doesn't care about ref call_or_other => { - let args_to_check; - let call_kind; - match *call_or_other { - Call(_, ref args) => { - call_kind = "function"; - args_to_check = &args[..]; - }, - MethodCall(_, ref args) => { - call_kind = "method"; - // first "argument" is self (which sometimes needs parens) - args_to_check = &args[1..]; - } + let (args_to_check, call_kind) = match *call_or_other { + Call(_, ref args) => (&args[..], "function"), + // first "argument" is self (which sometimes needs parens) + MethodCall(_, ref args) => (&args[1..], "method"), // actual catch-all arm _ => { return; } - } + }; // Don't lint if this is a nested macro expansion: otherwise, the lint could // trigger in situations that macro authors shouldn't have to care about, e.g., // when a parenthesized token tree matched in one macro expansion is matched as @@ -372,16 +363,11 @@ impl EarlyLintPass for UnusedParens { } fn check_stmt(&mut self, cx: &EarlyContext, s: &ast::Stmt) { - let (value, msg) = match s.node { - ast::StmtKind::Local(ref local) => { - match local.init { - Some(ref value) => (value, "assigned value"), - None => return, - } + if let ast::StmtKind::Local(ref local) = s.node { + if let Some(ref value) = local.init { + self.check_unused_parens_core(cx, &value, "assigned value", false); } - _ => return, - }; - self.check_unused_parens_core(cx, &value, msg, false); + } } } @@ -414,9 +400,8 @@ impl UnusedImportBraces { let orig_ident = items[0].0.prefix.segments.last().unwrap().ident; if orig_ident.name == keywords::SelfValue.name() { return; - } else { - node_ident = rename.unwrap_or(orig_ident); } + node_ident = rename.unwrap_or(orig_ident); } ast::UseTreeKind::Glob => { node_ident = ast::Ident::from_str("*"); diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 11e27a597fbca..222d1164667d3 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -971,7 +971,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { /// Undefined bytes impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { - // FIXME(solson): This is a very naive, slow version. + // FIXME: Add a fast version for the common, nonoverlapping case fn copy_undef_mask( &mut self, src: Pointer, diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 3f5a05f9d0ed8..f0ea93bfffd3e 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -382,6 +382,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { } ty::Error | ty::Infer(_) | + ty::UnnormalizedProjection(..) | ty::Projection(..) | ty::Param(_) | ty::GeneratorWitness(_) | diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index e3ec2e6b9ce02..2996fe0320042 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -272,6 +272,8 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>( overflows: vec![], }), + ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), + ty::Infer(..) | ty::Error => { // By the time this code runs, all type variables ought to // be fully resolved. diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 564ecae15dc35..285fed9544ddb 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -124,6 +124,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::Foreign(..) => Some(PointerKind::Thin), // We should really try to normalize here. ty::Projection(ref pi) => Some(PointerKind::OfProjection(pi)), + ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), ty::Opaque(def_id, substs) => Some(PointerKind::OfOpaque(def_id, substs)), ty::Param(ref p) => Some(PointerKind::OfParam(p)), // Insufficient type information. diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 17e0b0431da6e..f96c85ae7ae3f 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1637,9 +1637,39 @@ fn explicit_predicates_of<'a, 'tcx>( def_id: DefId, ) -> ty::GenericPredicates<'tcx> { use rustc::hir::*; + use rustc_data_structures::fx::FxHashSet; debug!("explicit_predicates_of(def_id={:?})", def_id); + /// A data structure with unique elements, which preserves order of insertion. + /// Preserving the order of insertion is important here so as not to break + /// compile-fail UI tests. + struct UniquePredicates<'tcx> { + predicates: Vec<(ty::Predicate<'tcx>, Span)>, + uniques: FxHashSet<(ty::Predicate<'tcx>, Span)>, + } + + impl<'tcx> UniquePredicates<'tcx> { + fn new() -> Self { + UniquePredicates { + predicates: vec![], + uniques: FxHashSet::default(), + } + } + + fn push(&mut self, value: (ty::Predicate<'tcx>, Span)) { + if self.uniques.insert(value) { + self.predicates.push(value); + } + } + + fn extend, Span)>>(&mut self, iter: I) { + for value in iter { + self.push(value); + } + } + } + let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); let node = tcx.hir.get(node_id); @@ -1649,7 +1679,7 @@ fn explicit_predicates_of<'a, 'tcx>( let icx = ItemCtxt::new(tcx, def_id); let no_generics = hir::Generics::empty(); - let mut predicates = vec![]; + let mut predicates = UniquePredicates::new(); let ast_generics = match node { Node::TraitItem(item) => &item.generics, @@ -1744,7 +1774,7 @@ fn explicit_predicates_of<'a, 'tcx>( // on a trait we need to add in the supertrait bounds and bounds found on // associated types. if let Some((_trait_ref, _)) = is_trait { - predicates = tcx.super_predicates_of(def_id).predicates; + predicates.extend(tcx.super_predicates_of(def_id).predicates); } // In default impls, we can assume that the self type implements @@ -1895,6 +1925,8 @@ fn explicit_predicates_of<'a, 'tcx>( })) } + let mut predicates = predicates.predicates; + // Subtle: before we store the predicates into the tcx, we // sort them so that predicates like `T: Foo` come // before uses of `U`. This avoids false ambiguity errors diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 95544da0b8e0d..1125de55a0668 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -336,6 +336,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { // types, where we use Error as the Self type } + ty::UnnormalizedProjection(..) | ty::GeneratorWitness(..) | ty::Infer(..) => { bug!("unexpected type encountered in \ diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 371b631723a39..9b305ad03b056 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2737,6 +2737,7 @@ impl<'tcx> Clean for Ty<'tcx> { ty::Closure(..) | ty::Generator(..) => Tuple(vec![]), // FIXME(pcwalton) + ty::UnnormalizedProjection(..) => panic!("UnnormalizedProjection"), ty::GeneratorWitness(..) => panic!("GeneratorWitness"), ty::Infer(..) => panic!("Infer"), ty::Error => panic!("Error"), diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 3de4a1bd4170b..7a5353bb60ff6 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -217,6 +217,35 @@ pub trait Error: Debug + Display { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, E: Error + 'a> From for Box { + /// Converts a type of [`Error`] into a box of dyn [`Error`]. + /// + /// # Examples + /// + /// ``` + /// use std::error::Error; + /// use std::fmt; + /// use std::mem; + /// + /// #[derive(Debug)] + /// struct AnError; + /// + /// impl fmt::Display for AnError { + /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + /// write!(f , "An error") + /// } + /// } + /// + /// impl Error for AnError { + /// fn description(&self) -> &str { + /// "Description of an error" + /// } + /// } + /// + /// let an_error = AnError; + /// assert!(0 == mem::size_of_val(&an_error)); + /// let a_boxed_error = Box::::from(an_error); + /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) + /// ``` fn from(err: E) -> Box { Box::new(err) } @@ -224,6 +253,41 @@ impl<'a, E: Error + 'a> From for Box { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, E: Error + Send + Sync + 'a> From for Box { + /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of dyn [`Error`] + + /// [`Send`] + [`Sync`]. + /// + /// # Examples + /// + /// ``` + /// use std::error::Error; + /// use std::fmt; + /// use std::mem; + /// + /// #[derive(Debug)] + /// struct AnError; + /// + /// impl fmt::Display for AnError { + /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + /// write!(f , "An error") + /// } + /// } + /// + /// impl Error for AnError { + /// fn description(&self) -> &str { + /// "Description of an error" + /// } + /// } + /// + /// unsafe impl Send for AnError {} + /// + /// unsafe impl Sync for AnError {} + /// + /// let an_error = AnError; + /// assert!(0 == mem::size_of_val(&an_error)); + /// let a_boxed_error = Box::::from(an_error); + /// assert!( + /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) + /// ``` fn from(err: E) -> Box { Box::new(err) } @@ -231,6 +295,19 @@ impl<'a, E: Error + Send + Sync + 'a> From for Box for Box { + /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. + /// + /// # Examples + /// + /// ``` + /// use std::error::Error; + /// use std::mem; + /// + /// let a_string_error = "a string error".to_string(); + /// let a_boxed_error = Box::::from(a_string_error); + /// assert!( + /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) + /// ``` fn from(err: String) -> Box { #[derive(Debug)] struct StringError(String); @@ -251,6 +328,18 @@ impl From for Box { #[stable(feature = "string_box_error", since = "1.6.0")] impl From for Box { + /// Converts a [`String`] into a box of dyn [`Error`]. + /// + /// # Examples + /// + /// ``` + /// use std::error::Error; + /// use std::mem; + /// + /// let a_string_error = "a string error".to_string(); + /// let a_boxed_error = Box::::from(a_string_error); + /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) + /// ``` fn from(str_err: String) -> Box { let err1: Box = From::from(str_err); let err2: Box = err1; @@ -260,6 +349,19 @@ impl From for Box { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, 'b> From<&'b str> for Box { + /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. + /// + /// # Examples + /// + /// ``` + /// use std::error::Error; + /// use std::mem; + /// + /// let a_str_error = "a str error"; + /// let a_boxed_error = Box::::from(a_str_error); + /// assert!( + /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) + /// ``` fn from(err: &'b str) -> Box { From::from(String::from(err)) } @@ -267,6 +369,18 @@ impl<'a, 'b> From<&'b str> for Box { #[stable(feature = "string_box_error", since = "1.6.0")] impl<'a> From<&'a str> for Box { + /// Converts a [`str`] into a box of dyn [`Error`]. + /// + /// # Examples + /// + /// ``` + /// use std::error::Error; + /// use std::mem; + /// + /// let a_str_error = "a str error"; + /// let a_boxed_error = Box::::from(a_str_error); + /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) + /// ``` fn from(err: &'a str) -> Box { From::from(String::from(err)) } @@ -274,6 +388,20 @@ impl<'a> From<&'a str> for Box { #[stable(feature = "cow_box_error", since = "1.22.0")] impl<'a, 'b> From> for Box { + /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. + /// + /// # Examples + /// + /// ``` + /// use std::error::Error; + /// use std::mem; + /// use std::borrow::Cow; + /// + /// let a_cow_str_error = Cow::from("a str error"); + /// let a_boxed_error = Box::::from(a_cow_str_error); + /// assert!( + /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) + /// ``` fn from(err: Cow<'b, str>) -> Box { From::from(String::from(err)) } @@ -281,6 +409,19 @@ impl<'a, 'b> From> for Box { #[stable(feature = "cow_box_error", since = "1.22.0")] impl<'a> From> for Box { + /// Converts a [`Cow`] into a box of dyn [`Error`]. + /// + /// # Examples + /// + /// ``` + /// use std::error::Error; + /// use std::mem; + /// use std::borrow::Cow; + /// + /// let a_cow_str_error = Cow::from("a str error"); + /// let a_boxed_error = Box::::from(a_cow_str_error); + /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) + /// ``` fn from(err: Cow<'a, str>) -> Box { From::from(String::from(err)) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index f2acdb3f469d1..83a05921510b4 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2228,6 +2228,9 @@ impl<'a> State<'a> { self.word_nbsp("async")?; self.print_capture_clause(capture_clause)?; self.s.space()?; + // cbox/ibox in analogy to the `ExprKind::Block` arm above + self.cbox(INDENT_UNIT)?; + self.ibox(0)?; self.print_block_with_attrs(blk, attrs)?; } ast::ExprKind::Assign(ref lhs, ref rhs) => { diff --git a/src/test/pretty/issue-54752-async-block.rs b/src/test/pretty/issue-54752-async-block.rs new file mode 100644 index 0000000000000..6930ee1a386fe --- /dev/null +++ b/src/test/pretty/issue-54752-async-block.rs @@ -0,0 +1,7 @@ +#![feature(async_await)] +#![allow(unused_parens)] + +// edition:2018 +// pp-exact + +fn main() { let _a = (async { }); } diff --git a/src/test/ui/chalkify/lower_env1.stderr b/src/test/ui/chalkify/lower_env1.stderr index d6673f6a8a6fb..4a3e14ac03472 100644 --- a/src/test/ui/chalkify/lower_env1.stderr +++ b/src/test/ui/chalkify/lower_env1.stderr @@ -5,9 +5,8 @@ LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: FromEnv(Self: Foo) :- FromEnv(Self: Bar). - = note: FromEnv(Self: Foo) :- FromEnv(Self: Bar). = note: Implemented(Self: Bar) :- FromEnv(Self: Bar). - = note: WellFormed(Self: Bar) :- Implemented(Self: Bar), WellFormed(Self: Foo), WellFormed(Self: Foo). + = note: WellFormed(Self: Bar) :- Implemented(Self: Bar), WellFormed(Self: Foo). error: program clause dump --> $DIR/lower_env1.rs:19:1 @@ -16,11 +15,10 @@ LL | #[rustc_dump_env_program_clauses] //~ ERROR program clause dump | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: FromEnv(Self: Foo) :- FromEnv(Self: Bar). - = note: FromEnv(Self: Foo) :- FromEnv(Self: Bar). = note: Implemented(Self: Bar) :- FromEnv(Self: Bar). = note: Implemented(Self: Foo) :- FromEnv(Self: Foo). = note: Implemented(Self: std::marker::Sized) :- FromEnv(Self: std::marker::Sized). - = note: WellFormed(Self: Bar) :- Implemented(Self: Bar), WellFormed(Self: Foo), WellFormed(Self: Foo). + = note: WellFormed(Self: Bar) :- Implemented(Self: Bar), WellFormed(Self: Foo). = note: WellFormed(Self: Foo) :- Implemented(Self: Foo). = note: WellFormed(Self: std::marker::Sized) :- Implemented(Self: std::marker::Sized). diff --git a/src/test/ui/if/ifmt-bad-arg.rs b/src/test/ui/if/ifmt-bad-arg.rs index bbd75f30d6cb1..6f051b40e8b65 100644 --- a/src/test/ui/if/ifmt-bad-arg.rs +++ b/src/test/ui/if/ifmt-bad-arg.rs @@ -71,4 +71,18 @@ fn main() { "##); //~^^^ ERROR: there is no argument named `foo` + + // bad syntax in format string with multiple newlines, #53836 + format!("first number: {} +second number: {} +third number: {} +fourth number: {} +fifth number: {} +sixth number: {} +seventh number: {} +eighth number: {} +ninth number: { +tenth number: {}", + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + //~^^ ERROR: invalid format string } diff --git a/src/test/ui/if/ifmt-bad-arg.stderr b/src/test/ui/if/ifmt-bad-arg.stderr index c8fd8bad19ba5..7e71707c22b16 100644 --- a/src/test/ui/if/ifmt-bad-arg.stderr +++ b/src/test/ui/if/ifmt-bad-arg.stderr @@ -204,5 +204,11 @@ error: there is no argument named `foo` LL | {foo} | ^^^^^ -error: aborting due to 27 previous errors +error: invalid format string: expected `'}'`, found `'t'` + --> $DIR/ifmt-bad-arg.rs:85:1 + | +LL | tenth number: {}", + | ^ expected `}` in format string + +error: aborting due to 28 previous errors