diff --git a/src/Cargo.lock b/src/Cargo.lock index cdc3a693648e8..98529bdab3ffd 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -209,6 +209,7 @@ dependencies = [ "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)", + "curl-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index ffc5adbebb34f..b5dc0090c8b9c 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -632,6 +632,9 @@ def build_bootstrap(self): target_features += ["-crt-static"] if target_features: env["RUSTFLAGS"] += "-C target-feature=" + (",".join(target_features)) + " " + target_linker = self.get_toml("linker", build_section) + if target_linker is not None: + env["RUSTFLAGS"] += "-C linker=" + target_linker + " " env["PATH"] = os.path.join(self.bin_root(), "bin") + \ os.pathsep + env["PATH"] diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 473730c548990..6958719536694 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -80,7 +80,8 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { elem: &PlaceElem<'tcx>) -> PlaceTy<'tcx> { - self.projection_ty_core(tcx, elem, |_, _, ty| ty) + self.projection_ty_core(tcx, elem, |_, _, ty| -> Result, ()> { Ok(ty) }) + .unwrap() } /// `place_ty.projection_ty_core(tcx, elem, |...| { ... })` @@ -88,11 +89,12 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { /// `Ty` or downcast variant corresponding to that projection. /// The `handle_field` callback must map a `Field` to its `Ty`, /// (which should be trivial when `T` = `Ty`). - pub fn projection_ty_core(self, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - elem: &ProjectionElem<'tcx, V, T>, - mut handle_field: impl FnMut(&Self, &Field, &T) -> Ty<'tcx>) - -> PlaceTy<'tcx> + pub fn projection_ty_core( + self, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + elem: &ProjectionElem<'tcx, V, T>, + mut handle_field: impl FnMut(&Self, &Field, &T) -> Result, E>) + -> Result, E> where V: ::std::fmt::Debug, T: ::std::fmt::Debug { @@ -142,10 +144,11 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { bug!("cannot downcast non-ADT type: `{:?}`", self) } }, - ProjectionElem::Field(ref f, ref fty) => PlaceTy::Ty { ty: handle_field(&self, f, fty) } + ProjectionElem::Field(ref f, ref fty) => + PlaceTy::Ty { ty: handle_field(&self, f, fty)? }, }; debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer); - answer + Ok(answer) } } diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 4eda47d31ebb5..2262516d376cd 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -888,7 +888,7 @@ fn project_type<'cx, 'gcx, 'tcx>( let recursion_limit = *selcx.tcx().sess.recursion_limit.get(); if obligation.recursion_depth >= recursion_limit { debug!("project: overflow!"); - selcx.infcx().report_overflow_error(&obligation, true); + return Err(ProjectionTyError::TraitSelectionError(SelectionError::Overflow)); } let obligation_trait_ref = &obligation.predicate.trait_ref(selcx.tcx()); diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 953fe0c9521e6..33bd009c8b565 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -991,20 +991,39 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { let v1 = ty::Contravariant.xform(v); let tcx = self.infcx.tcx; - let mut projected_ty = PlaceTy::from_ty(ty); + let ty = self.normalize(ty, locations); + + // We need to follow any provided projetions into the type. + // + // if we hit a ty var as we descend, then just skip the + // attempt to relate the mir local with any type. + #[derive(Debug)] struct HitTyVar; + let mut curr_projected_ty: Result; + + curr_projected_ty = Ok(PlaceTy::from_ty(ty)); for proj in &user_ty.projs { - projected_ty = projected_ty.projection_ty_core( + let projected_ty = if let Ok(projected_ty) = curr_projected_ty { + projected_ty + } else { + break; + }; + curr_projected_ty = projected_ty.projection_ty_core( tcx, proj, |this, field, &()| { - let ty = this.field_ty(tcx, field); - self.normalize(ty, locations) + if this.to_ty(tcx).is_ty_var() { + Err(HitTyVar) + } else { + let ty = this.field_ty(tcx, field); + Ok(self.normalize(ty, locations)) + } }); } debug!("user_ty base: {:?} freshened: {:?} projs: {:?} yields: {:?}", - user_ty.base, ty, user_ty.projs, projected_ty); + user_ty.base, ty, user_ty.projs, curr_projected_ty); - let ty = projected_ty.to_ty(tcx); - - self.relate_types(ty, v1, a, locations, category)?; + if let Ok(projected_ty) = curr_projected_ty { + let ty = projected_ty.to_ty(tcx); + self.relate_types(ty, v1, a, locations, category)?; + } } UserTypeAnnotation::TypeOf(def_id, canonical_substs) => { let ( diff --git a/src/librustc_traits/type_op.rs b/src/librustc_traits/type_op.rs index 2ed02a4cdab1e..e635bc9efc45c 100644 --- a/src/librustc_traits/type_op.rs +++ b/src/librustc_traits/type_op.rs @@ -151,17 +151,35 @@ impl AscribeUserTypeCx<'me, 'gcx, 'tcx> { debug!("relate_type_and_user_type: ty of def-id is {:?}", ty); let ty = self.normalize(ty); - let mut projected_ty = PlaceTy::from_ty(ty); + // We need to follow any provided projetions into the type. + // + // if we hit a ty var as we descend, then just skip the + // attempt to relate the mir local with any type. + + struct HitTyVar; + let mut curr_projected_ty: Result; + curr_projected_ty = Ok(PlaceTy::from_ty(ty)); for proj in projs { - projected_ty = projected_ty.projection_ty_core( + let projected_ty = if let Ok(projected_ty) = curr_projected_ty { + projected_ty + } else { + break; + }; + curr_projected_ty = projected_ty.projection_ty_core( tcx, proj, |this, field, &()| { - let ty = this.field_ty(tcx, field); - self.normalize(ty) + if this.to_ty(tcx).is_ty_var() { + Err(HitTyVar) + } else { + let ty = this.field_ty(tcx, field); + Ok(self.normalize(ty)) + } }); } - let ty = projected_ty.to_ty(tcx); - self.relate(mir_ty, variance, ty)?; + if let Ok(projected_ty) = curr_projected_ty { + let ty = projected_ty.to_ty(tcx); + self.relate(mir_ty, variance, ty)?; + } if let Some(UserSelfTy { impl_def_id, diff --git a/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs b/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs new file mode 100644 index 0000000000000..6d91fd3508a86 --- /dev/null +++ b/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs @@ -0,0 +1,31 @@ +// compile-pass + +// rust-lang/rust#55552: The strategy pnkfelix landed in PR #55274 +// (for ensuring that NLL respects user-provided lifetime annotations) +// did not handle the case where the ascribed type has some expliit +// wildcards (`_`) mixed in, and it caused an internal compiler error +// (ICE). +// +// This test is just checking that we do not ICE when such things +// occur. + +struct X; +struct Y; +struct Z; + +struct Pair { x: X, y: Y } + +pub fn join(oper_a: A, oper_b: B) -> (RA, RB) +where A: FnOnce() -> RA + Send, + B: FnOnce() -> RB + Send, + RA: Send, + RB: Send +{ + (oper_a(), oper_b()) +} + +fn main() { + let ((_x, _y), _z): (_, Z) = join(|| (X, Y), || Z); + + let (Pair { x: _x, y: _y }, Z): (_, Z) = join(|| Pair { x: X, y: Y }, || Z); +} diff --git a/src/test/ui/issues/issue-23122-2.stderr b/src/test/ui/issues/issue-23122-2.stderr index c43f8d7782397..9620f89338620 100644 --- a/src/test/ui/issues/issue-23122-2.stderr +++ b/src/test/ui/issues/issue-23122-2.stderr @@ -1,10 +1,11 @@ -error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next` +error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: std::marker::Sized` --> $DIR/issue-23122-2.rs:17:15 | LL | impl Next for GetNext { | ^^^^ | = help: consider adding a `#![recursion_limit="128"]` attribute to your crate + = note: required because of the requirements on the impl of `Next` for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` error: aborting due to previous error diff --git a/src/tools/cargo b/src/tools/cargo index efb7972a095bc..5d967343acae1 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit efb7972a095bcd043dfd55edca3a3fd1590b34c8 +Subproject commit 5d967343acae16fd7b53a61e6cd4e93a1ac6f199