Auto merge of #52953 - dsciarra:mv-codemap-sourcemap, r=petrochenkov
Rename CodeMap/FileMap to SourceMap/SourceFile
A first renaming for #51574
diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs
index 2203aef..fab7289 100644
--- a/src/librustc/traits/query/normalize.rs
+++ b/src/librustc/traits/query/normalize.rs
@@ -12,15 +12,15 @@
//! which folds deeply, invoking the underlying
//! `normalize_projection_ty` query when it encounters projections.
-use infer::{InferCtxt, InferOk};
use infer::at::At;
-use mir::interpret::{GlobalId, ConstValue};
+use infer::{InferCtxt, InferOk};
+use mir::interpret::{ConstValue, GlobalId};
use rustc_data_structures::small_vec::SmallVec;
-use traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
use traits::project::Normalized;
-use ty::{self, Ty, TyCtxt};
+use traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
use ty::fold::{TypeFoldable, TypeFolder};
use ty::subst::{Subst, Substs};
+use ty::{self, Ty, TyCtxt};
use super::NoSolution;
@@ -121,9 +121,36 @@
let concrete_ty = generic_ty.subst(self.tcx(), substs);
self.anon_depth += 1;
if concrete_ty == ty {
- bug!("infinite recursion generic_ty: {:#?}, substs: {:#?}, \
- concrete_ty: {:#?}, ty: {:#?}", generic_ty, substs, concrete_ty,
- ty);
+ // The type in question can only be inferred in terms of itself. This
+ // is likely a user code issue, not a compiler issue. Thus, we will
+ // induce a cycle error by calling the parent query again on the type.
+ //
+ // FIXME: Perhaps a better solution would be to have fold_ty()
+ // itself be a query. Then, a type fold cycle would be detected
+ // and reported more naturally as part of the query system, rather
+ // than forcing it here.
+ //
+ // FIXME: Need a better span than just one pointing to the type def.
+ // Should point to a defining use of the type that results in this
+ // un-normalizable state.
+ if let Some(param_env_lifted) =
+ self.tcx().lift_to_global(&self.param_env)
+ {
+ if let Some(ty_lifted) = self.tcx().lift_to_global(&concrete_ty) {
+ let span = self.tcx().def_span(def_id);
+ self.tcx()
+ .global_tcx()
+ .at(span)
+ .normalize_ty_after_erasing_regions(
+ param_env_lifted.and(ty_lifted),
+ );
+ self.tcx().sess.abort_if_errors();
+ }
+ }
+ // If a cycle error can't be emitted, indicate a NoSolution error
+ // and let the caller handle it.
+ self.error = true;
+ return concrete_ty;
}
let folded_ty = self.fold_ty(concrete_ty);
self.anon_depth -= 1;
@@ -149,8 +176,8 @@
let gcx = self.infcx.tcx.global_tcx();
let mut orig_values = SmallVec::new();
- let c_data =
- self.infcx.canonicalize_query(&self.param_env.and(*data), &mut orig_values);
+ let c_data = self.infcx
+ .canonicalize_query(&self.param_env.and(*data), &mut orig_values);
debug!("QueryNormalizer: c_data = {:#?}", c_data);
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
match gcx.normalize_projection_ty(c_data) {
diff --git a/src/test/ui/existential_types/no_inferrable_concrete_type.rs b/src/test/ui/existential_types/no_inferrable_concrete_type.rs
new file mode 100644
index 0000000..d236503
--- /dev/null
+++ b/src/test/ui/existential_types/no_inferrable_concrete_type.rs
@@ -0,0 +1,23 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Issue 52985: Cause cycle error if user code provides no use case that allows an existential type
+// to be inferred to a concrete type. This results in an infinite cycle during type normalization.
+
+#![feature(existential_type)]
+
+existential type Foo: Copy; //~ cycle detected
+
+// make compiler happy about using 'Foo'
+fn bar(x: Foo) -> Foo { x }
+
+fn main() {
+ let _: Foo = std::mem::transmute(0u8);
+}
diff --git a/src/test/ui/existential_types/no_inferrable_concrete_type.stderr b/src/test/ui/existential_types/no_inferrable_concrete_type.stderr
new file mode 100644
index 0000000..ffb4f4c
--- /dev/null
+++ b/src/test/ui/existential_types/no_inferrable_concrete_type.stderr
@@ -0,0 +1,11 @@
+error[E0391]: cycle detected when normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All }, value: Foo }`
+ --> $DIR/no_inferrable_concrete_type.rs:16:1
+ |
+LL | existential type Foo: Copy; //~ cycle detected
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: ...which again requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All }, value: Foo }`, completing the cycle
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.