diff options
| author | bors <bors@rust-lang.org> | 2016-03-16 08:02:15 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-03-16 08:02:15 -0700 |
| commit | fd5603b6fc8c130da50c2fd49bcd1188ef10a19e (patch) | |
| tree | 386ff7a5d6ffe78f61163685c35179fb0e957e75 | |
| parent | e68d40edf49496e8d7a9ab03d75c9de2096446c5 (diff) | |
| parent | 96d9408dd9c932d5302c357d37f1a0262dcb51a9 (diff) | |
| download | rust-fd5603b6fc8c130da50c2fd49bcd1188ef10a19e.tar.gz rust-fd5603b6fc8c130da50c2fd49bcd1188ef10a19e.zip | |
Auto merge of #32228 - jonas-schievink:diag1, r=sanxiyn
Normalize return type when checking for E0269 Fixes #31597 First time dealing with normalization. Maybe `normalize_associated_type` would be better here, but it seems to imply it's only used during trans.
| -rw-r--r-- | src/librustc/middle/liveness.rs | 20 | ||||
| -rw-r--r-- | src/test/run-pass/issue-31597.rs | 37 |
2 files changed, 53 insertions, 4 deletions
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 04240bf2875..0bfb830efc1 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -112,7 +112,9 @@ use self::VarKind::*; use dep_graph::DepNode; use middle::def::*; use middle::pat_util; -use middle::ty::{self, TyCtxt}; +use middle::ty::{self, TyCtxt, ParameterEnvironment}; +use middle::traits::{self, ProjectionMode}; +use middle::infer; use lint; use util::nodemap::NodeMap; @@ -1490,9 +1492,19 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { match fn_ret { ty::FnConverging(t_ret) - if self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() => { - - if t_ret.is_nil() { + if self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() => { + + let param_env = ParameterEnvironment::for_item(&self.ir.tcx, id); + let infcx = infer::new_infer_ctxt(&self.ir.tcx, + &self.ir.tcx.tables, + Some(param_env), + ProjectionMode::Any); + let cause = traits::ObligationCause::dummy(); + let norm = traits::fully_normalize(&infcx, + cause, + &t_ret); + + if norm.unwrap().is_nil() { // for nil return types, it is ok to not return a value expl. } else { let ends_with_stmt = match body.expr { diff --git a/src/test/run-pass/issue-31597.rs b/src/test/run-pass/issue-31597.rs new file mode 100644 index 00000000000..9acd6384b75 --- /dev/null +++ b/src/test/run-pass/issue-31597.rs @@ -0,0 +1,37 @@ +// Copyright 2016 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. + +trait Make { + type Out; + + fn make() -> Self::Out; +} + +impl Make for () { + type Out = (); + + fn make() -> Self::Out {} +} + +// Also make sure we don't hit an ICE when the projection can't be known +fn f<T: Make>() -> <T as Make>::Out { loop {} } + +// ...and that it works with a blanket impl +trait Tr { + type Assoc; +} + +impl<T: Make> Tr for T { + type Assoc = (); +} + +fn g<T: Make>() -> <T as Tr>::Assoc { } + +fn main() {} |
