Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
549bd55
resurrect research paper list #24004
Apr 9, 2015
c3aa057
Add regression test for #19097
aturon Apr 9, 2015
644a75e
Fix `borrow` docs
apasel422 Apr 9, 2015
69f63e9
Indicate keyword in doc comment is code-like
frewsxcv Apr 9, 2015
8578fee
Don't use skolemized parameters but rather fresh variables in
nikomatsakis Apr 9, 2015
9eb8528
Copyediting for 'variable bindings'
steveklabnik Apr 9, 2015
bf88539
TRPL: new introduction
steveklabnik Apr 9, 2015
06dc26d
More editing work on TRPL
steveklabnik Apr 9, 2015
7bb0cd7
Write the 'primitive types' section of TRPL
steveklabnik Apr 9, 2015
2a88b79
Add tests for E-needstest issues
lgrz Apr 10, 2015
16574e3
Replace the use of the rather randomly named boolean `custom` to mean
nikomatsakis Apr 9, 2015
5156b3a
Modify the codemap code to use more slices and to information about
nikomatsakis Apr 9, 2015
906a972
Add a new `span_suggestion` infrastructure. This lets you edit a snippet
nikomatsakis Apr 9, 2015
e313b33
Improve error message where a closure escapes fn while trying to borrow
nikomatsakis Apr 9, 2015
e66569e
Fix pow docs to not use Int
steveklabnik Apr 10, 2015
cdce32f
Changed the wording of the documentation for the insert method for Ve…
djallen89 Apr 10, 2015
c2fa1f7
Doc: remove a "safety note" made obsolete by dropck for TypedArena
SimonSapin Apr 10, 2015
7bf1da1
s/Panicks/Panics/
apasel422 Apr 10, 2015
288b1c9
Add examples for Convert
steveklabnik Apr 6, 2015
9e68d23
Fix mistake in documentation
xamgore Apr 10, 2015
59ebc20
Rollup merge of #24121 - steveklabnik:gh24107, r=steveklabnik
steveklabnik Apr 10, 2015
7b415a9
Rollup merge of #24234 - thiagooak:academic-research, r=steveklabnik
steveklabnik Apr 10, 2015
4801260
Rollup merge of #24236 - aturon:issue-19097, r=alexcrichton
steveklabnik Apr 10, 2015
7725c8d
Rollup merge of #24239 - steveklabnik:editing_pass, r=steveklabnik
steveklabnik Apr 10, 2015
cadfcc5
Rollup merge of #24240 - apasel422:patch-1, r=aturon
steveklabnik Apr 10, 2015
29e110e
Rollup merge of #24242 - nikomatsakis:escaping-closure-error-message,…
steveklabnik Apr 10, 2015
bb2cdc1
Rollup merge of #24243 - frewsxcv:patch-13, r=steveklabnik
steveklabnik Apr 10, 2015
ede2761
Rollup merge of #24244 - steveklabnik:more_editing, r=steveklabnik
steveklabnik Apr 10, 2015
2dd17d7
Rollup merge of #24245 - nikomatsakis:issue-24241-coherence-failure, …
steveklabnik Apr 10, 2015
c381844
Rollup merge of #24247 - steveklabnik:update_variable_bindings, r=huonw
steveklabnik Apr 10, 2015
4aea07a
Rollup merge of #24253 - steveklabnik:doc_primitive_types, r=alexcric…
steveklabnik Apr 10, 2015
bbec378
Rollup merge of #24259 - lstat:needstest, r=alexcrichton
steveklabnik Apr 10, 2015
f940465
Rollup merge of #24274 - steveklabnik:fix_pow_docs, r=nikomatsakis
steveklabnik Apr 10, 2015
69ae855
Rollup merge of #24279 - libfud:vec_insertion_docs, r=steveklabnik
steveklabnik Apr 10, 2015
019af46
Rollup merge of #24282 - SimonSapin:patch-6, r=pnkfelix
steveklabnik Apr 10, 2015
c9976a1
Rollup merge of #24283 - apasel422:patch-2, r=alexcrichton
steveklabnik Apr 10, 2015
fbe2ec1
Rollup merge of #24291 - xamgore:patch-1, r=steveklabnik
steveklabnik Apr 10, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Don't use skolemized parameters but rather fresh variables in
coherence. Skolemized parameters wind up preventing unification.
Surprised we had no test for this! Fixes #24241.
  • Loading branch information
nikomatsakis committed Apr 9, 2015
commit 8578fee5d823979ea760e1633eefa003db98cb0c
42 changes: 21 additions & 21 deletions src/librustc/middle/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use syntax::codemap::{DUMMY_SP, Span};
use util::ppaux::Repr;

#[derive(Copy, Clone)]
struct ParamIsLocal(bool);
struct InferIsLocal(bool);

/// True if there exist types that satisfy both of the two given impls.
pub fn overlapping_impls(infcx: &InferCtxt,
Expand Down Expand Up @@ -60,7 +60,7 @@ fn overlap(selcx: &mut SelectionContext,

let (a_trait_ref, a_obligations) = impl_trait_ref_and_oblig(selcx,
a_def_id,
util::free_substs_for_impl);
util::fresh_type_vars_for_impl);

let (b_trait_ref, b_obligations) = impl_trait_ref_and_oblig(selcx,
b_def_id,
Expand Down Expand Up @@ -104,7 +104,7 @@ pub fn trait_ref_is_knowable<'tcx>(tcx: &ty::ctxt<'tcx>, trait_ref: &ty::TraitRe

// if the orphan rules pass, that means that no ancestor crate can
// impl this, so it's up to us.
if orphan_check_trait_ref(tcx, trait_ref, ParamIsLocal(false)).is_ok() {
if orphan_check_trait_ref(tcx, trait_ref, InferIsLocal(false)).is_ok() {
debug!("trait_ref_is_knowable: orphan check passed");
return true;
}
Expand All @@ -126,7 +126,7 @@ pub fn trait_ref_is_knowable<'tcx>(tcx: &ty::ctxt<'tcx>, trait_ref: &ty::TraitRe
// implemented by an upstream crate, which means that the impl
// must be visible to us, and -- since the trait is fundamental
// -- we can test.
orphan_check_trait_ref(tcx, trait_ref, ParamIsLocal(true)).is_err()
orphan_check_trait_ref(tcx, trait_ref, InferIsLocal(true)).is_err()
}

type SubstsFn = for<'a,'tcx> fn(infcx: &InferCtxt<'a, 'tcx>,
Expand Down Expand Up @@ -196,16 +196,16 @@ pub fn orphan_check<'tcx>(tcx: &ty::ctxt<'tcx>,
return Ok(());
}

orphan_check_trait_ref(tcx, &trait_ref, ParamIsLocal(false))
orphan_check_trait_ref(tcx, &trait_ref, InferIsLocal(false))
}

fn orphan_check_trait_ref<'tcx>(tcx: &ty::ctxt<'tcx>,
trait_ref: &ty::TraitRef<'tcx>,
param_is_local: ParamIsLocal)
infer_is_local: InferIsLocal)
-> Result<(), OrphanCheckErr<'tcx>>
{
debug!("orphan_check_trait_ref(trait_ref={}, param_is_local={})",
trait_ref.repr(tcx), param_is_local.0);
debug!("orphan_check_trait_ref(trait_ref={}, infer_is_local={})",
trait_ref.repr(tcx), infer_is_local.0);

// First, create an ordered iterator over all the type parameters to the trait, with the self
// type appearing first.
Expand All @@ -215,12 +215,12 @@ fn orphan_check_trait_ref<'tcx>(tcx: &ty::ctxt<'tcx>,
// Find the first input type that either references a type parameter OR
// some local type.
for input_ty in input_tys {
if ty_is_local(tcx, input_ty, param_is_local) {
if ty_is_local(tcx, input_ty, infer_is_local) {
debug!("orphan_check_trait_ref: ty_is_local `{}`", input_ty.repr(tcx));

// First local input type. Check that there are no
// uncovered type parameters.
let uncovered_tys = uncovered_tys(tcx, input_ty, param_is_local);
let uncovered_tys = uncovered_tys(tcx, input_ty, infer_is_local);
for uncovered_ty in uncovered_tys {
if let Some(param) = uncovered_ty.walk().find(|t| is_type_parameter(t)) {
debug!("orphan_check_trait_ref: uncovered type `{}`", param.repr(tcx));
Expand All @@ -234,7 +234,7 @@ fn orphan_check_trait_ref<'tcx>(tcx: &ty::ctxt<'tcx>,

// Otherwise, enforce invariant that there are no type
// parameters reachable.
if !param_is_local.0 {
if !infer_is_local.0 {
if let Some(param) = input_ty.walk().find(|t| is_type_parameter(t)) {
debug!("orphan_check_trait_ref: uncovered type `{}`", param.repr(tcx));
return Err(OrphanCheckErr::UncoveredTy(param));
Expand All @@ -249,14 +249,14 @@ fn orphan_check_trait_ref<'tcx>(tcx: &ty::ctxt<'tcx>,

fn uncovered_tys<'tcx>(tcx: &ty::ctxt<'tcx>,
ty: Ty<'tcx>,
param_is_local: ParamIsLocal)
infer_is_local: InferIsLocal)
-> Vec<Ty<'tcx>>
{
if ty_is_local_constructor(tcx, ty, param_is_local) {
if ty_is_local_constructor(tcx, ty, infer_is_local) {
vec![]
} else if fundamental_ty(tcx, ty) {
ty.walk_shallow()
.flat_map(|t| uncovered_tys(tcx, t, param_is_local).into_iter())
.flat_map(|t| uncovered_tys(tcx, t, infer_is_local).into_iter())
.collect()
} else {
vec![ty]
Expand All @@ -271,10 +271,10 @@ fn is_type_parameter<'tcx>(ty: Ty<'tcx>) -> bool {
}
}

fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>, param_is_local: ParamIsLocal) -> bool
fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>, infer_is_local: InferIsLocal) -> bool
{
ty_is_local_constructor(tcx, ty, param_is_local) ||
fundamental_ty(tcx, ty) && ty.walk_shallow().any(|t| ty_is_local(tcx, t, param_is_local))
ty_is_local_constructor(tcx, ty, infer_is_local) ||
fundamental_ty(tcx, ty) && ty.walk_shallow().any(|t| ty_is_local(tcx, t, infer_is_local))
}

fn fundamental_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool
Expand All @@ -293,7 +293,7 @@ fn fundamental_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool

fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>,
ty: Ty<'tcx>,
param_is_local: ParamIsLocal)
infer_is_local: InferIsLocal)
-> bool
{
debug!("ty_is_local_constructor({})", ty.repr(tcx));
Expand All @@ -310,13 +310,13 @@ fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>,
ty::ty_ptr(..) |
ty::ty_rptr(..) |
ty::ty_tup(..) |
ty::ty_infer(..) |
ty::ty_param(..) |
ty::ty_projection(..) => {
false
}

ty::ty_param(..) => {
param_is_local.0
ty::ty_infer(..) => {
infer_is_local.0
}

ty::ty_enum(def_id, _) |
Expand Down
29 changes: 0 additions & 29 deletions src/librustc/middle/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use middle::region;
use middle::subst::{Substs, VecPerParamSpace};
use middle::infer::InferCtxt;
use middle::ty::{self, Ty, AsPredicate, ToPolyTraitRef};
Expand Down Expand Up @@ -304,34 +303,6 @@ pub fn fresh_type_vars_for_impl<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
infcx.fresh_substs_for_generics(span, &impl_generics)
}

// determine the `self` type, using fresh variables for all variables
// declared on the impl declaration e.g., `impl<A,B> for Box<[(A,B)]>`
// would return ($0, $1) where $0 and $1 are freshly instantiated type
// variables.
pub fn free_substs_for_impl<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
_span: Span,
impl_def_id: ast::DefId)
-> Substs<'tcx>
{
let tcx = infcx.tcx;
let impl_generics = ty::lookup_item_type(tcx, impl_def_id).generics;

let some_types = impl_generics.types.map(|def| {
ty::mk_param_from_def(tcx, def)
});

let some_regions = impl_generics.regions.map(|def| {
// FIXME. This destruction scope information is pretty darn
// bogus; after all, the impl might not even be in this crate!
// But given what we do in coherence, it is harmless enough
// for now I think. -nmatsakis
let extent = region::DestructionScopeData::new(ast::DUMMY_NODE_ID);
ty::free_region_from_def(extent, def)
});

Substs::new(some_types, some_regions)
}

impl<'tcx, N> fmt::Debug for VtableImplData<'tcx, N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "VtableImpl({:?})", self.impl_def_id)
Expand Down
28 changes: 28 additions & 0 deletions src/test/compile-fail/coherence-overlap-all-t-and-tuple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2015 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.

// Check that we detect an overlap here in the case where:
//
// for some type X:
// T = (X,)
// T11 = X, U11 = X
//
// Seems pretty basic, but then there was issue #24241. :)

trait From<U> {
}

impl <T> From<T> for T { //~ ERROR E0119
}

impl <T11, U11> From<(U11,)> for (T11,) {
}

fn main() { }